<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"><title>一文详解Stream流 | 狼族少年、血狼</title><meta name="author" content="狼族少年、血狼"><meta name="copyright" content="狼族少年、血狼"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="简介Stream支持元素流功能性操作的类，例如集合上的map-reduce转换。 例如： 1int sum &#x3D; widgets.stream().filter(b -&gt; b.getColor() &#x3D;&#x3D; RED).mapToInt(b -&gt; b.getWeight()).sum();    这里我们使用widgets Collection&lt;Widget&gt;作为流的源，然后在流上">
<meta property="og:type" content="article">
<meta property="og:title" content="一文详解Stream流">
<meta property="og:url" content="https://geekwolfman.github.io/2023/05/02/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Stream%E6%B5%81.html">
<meta property="og:site_name" content="狼族少年、血狼">
<meta property="og:description" content="简介Stream支持元素流功能性操作的类，例如集合上的map-reduce转换。 例如： 1int sum &#x3D; widgets.stream().filter(b -&gt; b.getColor() &#x3D;&#x3D; RED).mapToInt(b -&gt; b.getWeight()).sum();    这里我们使用widgets Collection&lt;Widget&gt;作为流的源，然后在流上">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Stream%E6%B5%81/00cover.jpg">
<meta property="article:published_time" content="2023-05-02T15:37:56.000Z">
<meta property="article:modified_time" content="2023-05-02T15:48:56.200Z">
<meta property="article:author" content="狼族少年、血狼">
<meta property="article:tag" content="java基础">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Stream%E6%B5%81/00cover.jpg"><link rel="shortcut icon" href="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/config/avatar/avatar.png"><link rel="canonical" href="https://geekwolfman.github.io/2023/05/02/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Stream%E6%B5%81.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"/db.json","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false,
  percent: {
    toc: true,
    rightside: true,
  }
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '一文详解Stream流',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2023-05-02 23:48:56'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
    win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
      const link = document.createElement('link')
      link.rel = 'stylesheet'
      link.href = url
      if (id) link.id = id
      link.onerror = reject
      link.onload = link.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        link.onload = link.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(link)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/pace-js/themes/blue/pace-theme-minimal.min.css"/><script src="https://cdn.jsdelivr.net/npm/pace-js/pace.min.js"></script><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/config/avatar/avatar.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">57</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">14</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">9</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/gallery/"><i class="fa-fw fas fa-images"></i><span> 画廊</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-paper-plane"></i><span> 关于</span></a></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Stream%E6%B5%81/00cover.jpg')"><nav id="nav"><span id="blog-info"><a href="/" title="狼族少年、血狼"><span class="site-name">狼族少年、血狼</span></a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search" href="javascript:void(0);"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 归档</span></a></div><div class="menus_item"><a class="site-page" href="/gallery/"><i class="fa-fw fas fa-images"></i><span> 画廊</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-paper-plane"></i><span> 关于</span></a></div></div><div id="toggle-menu"><a class="site-page" href="javascript:void(0);"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">一文详解Stream流</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2023-05-02T15:37:56.000Z" title="发表于 2023-05-02 23:37:56">2023-05-02</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2023-05-02T15:48:56.200Z" title="更新于 2023-05-02 23:48:56">2023-05-02</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/java/">java</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">32.9k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>141分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="一文详解Stream流"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>Stream支持元素流功能性操作的类，例如集合上的<code>map-reduce</code>转换。 例如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> widgets.stream().filter(b -&gt; b.getColor() == RED).mapToInt(b -&gt; b.getWeight()).sum();  </span><br></pre></td></tr></table></figure>

<p>这里我们使用<code>widgets Collection&lt;Widget&gt;</code>作为流的源，然后在流上执行filter-map-reduce以获得红色小部件的权重之和。（求和是一个的例子reduction操作）。</p>
<p>这个包中引入的关键抽象是流。流与集合有以下几种不同：</p>
<ul>
<li>没有存储。 流不是存储元素的数据结构;  相反，它通过计算操作的流水线传送诸如数据结构，数组，生成器功能或I&#x2F;O通道的源的元件。</li>
<li>功能性质。 流上的操作产生结果，但不会修改其来源。  例如，过滤从Stream获得的Stream会生成旧的Stream不需要的元素，而不是从源集合中删除元素。</li>
<li>懒惰执行。 许多流操作（如过滤，映射或重复删除）可以懒惰地实现，从而暴露优化的机会。  例如，”找到具有三个连续元音的第一个String”，不需要检查所有的输入字符串。  流操作分为中间（Stream生产）操作和终端（价值或副作用生成）操作。  中间操作总是懒惰执行的。</li>
<li>可能无限。 虽然集合的大小有限，但流不需要。  诸如limit(n)或findFirst()之类的方法可以允许无限流上的计算在有限的时间内完成。</li>
<li>消耗性质。流的元素只能在流的一生中访问一次。 像Iterator一样 ，必须生成一个新流来重新访问源的相同元素。</li>
</ul>
<p>流可以通过多种方式获得。 一些例子包括：</p>
<ul>
<li>通过Collection的stream()或parallelStream()方法；</li>
<li>对于数组类可以通过Arrays.stream(Object[])获取流；</li>
<li>通过高级流类的静态方法，如Stream.of(Object[])、IntStream.range(int,  int)、Stream.iterate(Object,  UnaryOperator); ；</li>
<li>文件的行可以从BufferedReader.lines()获取;</li>
<li>文件路径的流可以从Files中的方法获得，如newDirectoryStream()、newInputStream()、newOutputStream()；</li>
<li>随机数流可以从Random.ints()获得;</li>
<li>许多其它的数据流的方法的轴承在JDK中，包括BitSet.stream()、Pattern.splitAsStream(java.lang.CharSequence)、JarFile.stream()；</li>
</ul>
<p>流操作分为<strong>中间操作和终端操作</strong>，并且组合以形成pipelines。pipelines由源（例如Collection，数组，发生器功能或I&#x2F;O通道）组成；其次是零个或多个中间操作，如Stream.filter或Stream.map；以及诸如Stream.forEach或Stream.reduce的终端操作。</p>
<p>中间操作返回一个新的流。 他们总是<strong>懒惰</strong>执行诸如filter()操作实际上不执行任何过滤，而是创建一个新的流，当被遍历时，它包含与给定谓词匹配的初始流的元素。在管道的终端操作被执行之前，管道源的遍历不会开始。</p>
<p>诸如Stream.forEach或IntStream.sum终端操作可以遍历流以产生结果或副作用。在执行终端操作之后，流管道被认为被消耗，并且不能再使用；如果再次遍历相同的数据源，则必须返回到数据源以获取新的流。 在几乎所有情况下，终端操作都是迫切的，在返回之前完成对数据源的遍历和处理。只有终端操作iterator()和spliterator()不是；在现有操作不足以满足任务的情况下，这些提供为”逃生舱“，以允许任意客户端控制的管道遍历。</p>
<p>处理流<strong>懒惰实现有着</strong>显著的效率提升; 在诸如上述的filter-map-reduce的流水线中，过滤、映射和求和可以融合到数据的单次传递中，具有最小的中间状态。懒惰也允许避免在没有必要时检查所有数据；对于诸如“找到长度超过1000个字符的第一个字符串”等操作，只需检查足够的字符串即可找到具有所需特性的字符串，而无需检查源中可用的所有字符串。（当输入流是无限大而不仅仅是大的时候，这种行为变得更加重要）</p>
<p>中间操作进一步分为无状态操作和有状态操作。无状态操作（例如filter和map）在处理新元素时不保留先前看到的元素的状态——每个元素可以独立于其他元素的操作进行处理。  诸如distinct和sorted有状态操作可以在处理新元件时结合先前看到的元素的状态。</p>
<p>在产生结果之前，有状态操作可能需要处理整个输入。例如，在流已经看到流的所有元素之前，不能产生排序流的任何结果。<strong>因此，在并行计算下，包含有状态中间操作的一些流水线可能需要对数据进行多遍，或者可能需要缓冲重要的数据。  包含无状态中间操作的流水线可以在一次通过中处理，无论是顺序还是并行，具有最少的数据缓冲。</strong></p>
<p>此外，一些操作被认为是<strong>短路操作</strong>。如果在无限输入的情况下，中间运算可能会产生有限的流，这种情况就叫做短路。如果当无限输入呈现时，终端操作可能会在有限时间内终止。在流水线中进行短路操作是处理无限流在有限时间内正常终止的必要但不足够的条件。</p>
<h1 id="特性"><a href="#特性" class="headerlink" title="特性"></a>特性</h1><h2 id="并行性"><a href="#并行性" class="headerlink" title="并行性"></a>并行性</h2><p>具有显式for循环的处理元素方式是串行的。流通过将计算重构为聚合操作的管道来促进并行执行，而不是作为每个单独元素的必要操作。<strong>所有流操作可以串行或并行执行。</strong>JDK中的流实现创建串行流，除非显式请求并行。 例如，  Collection具有方法Collection.stream()和Collection.parallelStream()，其分别产生顺序和并行流；虽然IntStream.range(int,  int)等其他流承载方法产生顺序流，但是可以通过调用它们的BaseStream.parallel()方法来有效地并行化这些流。要并行执行先前的“小部件权重总和”查询，我们可以这样做：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sumOfWeights</span> <span class="operator">=</span> widgets.parallelStream().filter(b -&gt; b.getColor() == RED) .mapToInt(b -&gt; b.getWeight()).sum();  </span><br></pre></td></tr></table></figure>

<p>此示例的串行和并行版本之间的唯一区别是创建初始流，使用parallelStream()而不是stream()。当终端操作被启动时，根据被调用的流的方向，顺序或并行地执行流管道。流是否以串行或并行方式执行可以使用isParallel()方法确定，并且可以使用BaseStream.sequential()和BaseStream.parallel()操作修改流的方向。当终端操作被启动时，根据其被调用的流的模式，顺序地或并行地执行pipelines。</p>
<p>除了确定为非确定性的操作，如findAny()，流是顺序还是并行执行，不应该改变计算结果。</p>
<p>大多数流操作接受描述用户指定行为的参数，这些行为通常是lambda表达式。为了保持正确的行为，这些行为参数必须是非干扰的，在大多数情况下必须是无状态的。这样的参数总是functional interface的例子 ，如Function，并且通常是lambda表达式或方法引用。</p>
<h2 id="非干扰"><a href="#非干扰" class="headerlink" title="非干扰"></a>非干扰</h2><p>Streams能够对各种数据源执行可能并行的聚合操作，包括甚至非线程安全的集合，如ArrayList。只有当我们能够在流管道的执行过程中防止对数据源的干扰时，这才有可能。除了逃生舱操作iterator()和spliterator()，当调用终端操作时开始执行，终端操作完成时结束。对于大多数数据源，防止干扰意味着确保在pipelines的执行期间完全<strong>不修改</strong>数据源。其中值得注意的例外是其源是并发集合的流，它们专门用于处理并发修改。并发流源是指Spliterator报告CONCURRENT特征的流源。。</p>
<p>因此，源可能不是并发的流管道中的行为参数永远不应该修改流的数据源。如果行为参数修改或导致修改流的数据源，则它会干扰非并发数据源。不干涉的必要性适用于所有管道，而不仅仅是平行管道。除非流源是并发的，否则在流管道的执行过程中修改流的数据源可能会导致异常、错误回答或不一致行为。对于性能良好的流源，可以在终端操作开始之前修改源，并且这些修改将反映在所覆盖的元素中。例如，考虑以下代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; l = <span class="keyword">new</span> <span class="title class_">ArrayList</span>(Arrays.asList(<span class="string">&quot;one&quot;</span>, <span class="string">&quot;two&quot;</span>));</span><br><span class="line">Stream&lt;String&gt; sl = l.stream(); </span><br><span class="line">l.add(<span class="string">&quot;three&quot;</span>); </span><br><span class="line"><span class="type">String</span> <span class="variable">s</span> <span class="operator">=</span> sl.collect(joining(<span class="string">&quot; &quot;</span>));  </span><br></pre></td></tr></table></figure>

<p>首先创建一个由两个字符串组成的列表：“one”、“two”。 然后从该列表创建流。接下来，通过添加第三个字符串“three”修改列表。最后，流的元素被收集并连接在一起。由于列表在终端collect操作开始之前被修改，所以结果将是一个“one two three”的字符串。从JDK集合返回的所有流和大多数其他JDK类都以这种方式表现良好；对于其他库生成的流，请参阅Low-level stream construction，了解构建良好流的要求。</p>
<h2 id="有状态"><a href="#有状态" class="headerlink" title="有状态"></a>有状态</h2><p>如果流操作的行为参数是<strong>有状态</strong>的，流管道结果可能不确定或不正确。有状态的lambda（或实现适当的功能接口的其他对象）是结果取决于在流管道的执行期间可能改变的任何状态。有状态的lambda的一个例子是map()的<code>map()</code> ：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Set&lt;Integer&gt; seen = Collections.synchronizedSet(<span class="keyword">new</span> <span class="title class_">HashSet</span>&lt;&gt;());</span><br><span class="line">stream.parallel().map(e -&gt; &#123;</span><br><span class="line">    <span class="keyword">if</span> (seen.add(e)) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">return</span> e;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<p>这里，如果并行执行映射操作，由于线程调度的差异，相同输入的结果可能因运行而异，而使用无状态的lambda表达式，结果总是相同的。</p>
<p>还要注意，尝试从行为参数访问可变状态会带来安全和性能方面的不良选择；如果不同步对该状态的访问，则会有数据竞争，因此代码已损坏，但是如果同步访问该状态，则冒有争议的风险有可能破坏您正在寻求的并行性。最好的方法是避免有状态的行为参数完全流式传输；通常有一种重组流管道以避免状态的方法。</p>
<h2 id="副作用"><a href="#副作用" class="headerlink" title="副作用"></a>副作用</h2><p>一般而言，流行为的行为参数的副作用是不鼓励的，因为它们经常会导致无意识地违反无状态要求以及其他线程安全危害。</p>
<p>如果行为参数确实有副作用，除非明确说明，有没有保证，而在visibility的那些副作用给其他线程，也没有任何保证相同的流管道内的“相同”的元素在不同的操作在同一个线程中执行。此外，这些效果的排序可能是令人惊讶的。 即使当管道被限制以产生与流源的遇到顺序一致的结果（例如，<code>IntStream.range(0,5).parallel().map(x -&gt;  x*2).toArray()</code>必须产生<code>[0, 2, 4, 6, 8]</code>）时，不保证将映射器功能应用于各个元件的顺序，或者在什么线程中为给定元素执行任何行为参数。</p>
<p>许多可能诱惑使用副作用的计算可以更安全有效地表达而无副作用，例如使用reduction代替可变累加器。但是，对于调试目的使用println()等副作用通常是无害的。少量流操作，如forEach()和peek() ，只能通过副作用进行操作；这些应谨慎使用。</p>
<p>作为如何将不正确地使用副作用的流管道转换为不适用的流管道的示例，以下代码搜索与给定正则表达式匹配的字符串，并将匹配放在列表中。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">ArrayList&lt;String&gt; results = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">stream.filter(s -&gt; pattern.matcher(s).matches()).forEach(s -&gt; results.add(s)); <span class="comment">// Unnecessary use of side-effects!  </span></span><br></pre></td></tr></table></figure>

<p>此代码不必要地使用副作用。如果并行执行，ArrayList的非线程安全性将导致不正确的结果，并且添加所需的同步将导致争用，从而破坏并行性的好处。此外，这里使用副作用是完全不必要的；forEach()可以简单地替换为更安全、更高效、更适合并行化的collect操作：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; results = stream.filter(s -&gt; pattern.matcher(s).matches()).collect(Collectors.toList()); <span class="comment">// No side-effects!  </span></span><br></pre></td></tr></table></figure>

<h2 id="有序性"><a href="#有序性" class="headerlink" title="有序性"></a>有序性</h2><p>流可能有也可能没有定义的<strong>遇到顺序</strong> 。流是否有遇到顺序取决于源和中间操作。某些流源（如List或数组）本质上是有序的，而其他数据源（如HashSet ）不是。一些中间操作（例如sorted()）可以在其他无序流上施加遇到命令，而其他中间操作可以使有序流无序，例如BaseStream.unordered()。此外，一些终端操作可能会忽略遇到的顺序，如forEach() 。</p>
<p>如果一个流被操作，大多数操作被限制为在遇到的顺序中对元素进行操作; 如果流的源是List含有<code>[1, 2, 3]</code> ，然后执行的结果<code>map(x -&gt;  x*2)</code>必须是<code>[2, 4, 6]</code>。然而，如果源没有定义遇到顺序，则值<code>[2,  4, 6]</code>任何<code>[2, 4, 6]</code>将是有效结果。</p>
<p><strong>对于顺序流，遇到顺序的存在或不存在不影响性能，仅影响确定性。</strong>如果流被排序，在相同的源上重复执行相同的流管线将产生相同的结果;  如果没有顺序，重复执行可能会产生不同的结果。</p>
<p><strong>对于并行流，放宽排序约束有时可以实现更有效的执行。</strong>某些聚合操作，例如过滤重复（distinct()）或组合减少（Collectors.groupingBy()）可以更有效地实现，如果元素的排序不相关。类似地，本质上与遇到顺序相关的操作，如limit()可能需要缓冲以确保正确排序，从而破坏并行性的好处。在流具有相遇顺序，但用户并不特别关心该相遇顺序的情况下，使用unordered()方法显式地取消流的排序可以提高一些有状态或终端操作的并行性能。然而，大多数pipelines，如上面的“块的权重之和”示例，即使在排序约束下，仍然可以有效地并行化。</p>
<h2 id="归约操作"><a href="#归约操作" class="headerlink" title="归约操作"></a>归约操作</h2><p>归约操作（也称为折叠）采用一系列输入元素，并通过重复应用组合运算将它们组合成一个汇总结果，例如找到一组数字的和或最大值，或将元素累积到列表中。流类具有多种形式的通用归约运算，称为reduce()和collect()，以及多种专门的归约形式，如sum()、max()或count()。</p>
<p>当然，这样的操作可以容易使用简单的顺序循环实现，如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> <span class="number">0</span>; </span><br><span class="line"><span class="keyword">for</span> (<span class="type">int</span> x : numbers) &#123; </span><br><span class="line">    sum += x;</span><br><span class="line">&#125;  </span><br></pre></td></tr></table></figure>

<p>然而，有一个很好的理由使用归约操作超过如上所述的突变积累。不仅减少“更抽象”——它在整个流上运行，而不是单个元素，但正确构造的归约操作本质上是可并行的，只要用于处理元素的功能是associative和stateless。例如，给定一个我们要找到的数字的数据流，我们可以写：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> numbers.stream().reduce(<span class="number">0</span>, (x,y) -&gt; x+y);  </span><br></pre></td></tr></table></figure>

<p>要么：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> numbers.stream().reduce(<span class="number">0</span>, Integer::sum);  </span><br></pre></td></tr></table></figure>

<p>这些还原操作可以安全地并行运行，几乎没有修改：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> numbers.parallelStream().reduce(<span class="number">0</span>, Integer::sum);  </span><br></pre></td></tr></table></figure>

<p>归约可以很好地并行化，因为实现可以并行地对数据子集进行操作，然后将中间结果组合起来以获得最终的正确答案。（即使该语言有一个“每个并行”的构造，可变累积方法仍然需要开发人员为共享的累积变量sum提供线程安全的更新，然后所需的同步可能会消除并行带来的任何性能增益。）使用reduce()来消除并行化reduce操作的所有负担，并且该库可以提供高效的并行实现，而不需要额外的同步。</p>
<p>前面显示的“widgets”示例显示了如何将reduce与其他操作结合来替代大量操作的循环。如果widgets是Widget对象的集合，它们具有getWeight方法，我们可以找到最重的小部件：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">OptionalInt</span> <span class="variable">heaviest</span> <span class="operator">=</span> widgets.parallelStream().mapToInt(Widget::getWeight).max();  </span><br></pre></td></tr></table></figure>

<p>在其更一般的形式中，reduce上类型的元素的操作<T>得到类型的结果<code>&lt;U&gt;</code>需要三个参数：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;U&gt; U <span class="title function_">reduce</span><span class="params">(U identity, BiFunction&lt;U, ? <span class="built_in">super</span> T, U&gt; accumulator, BinaryOperator&lt;U&gt; combiner)</span>;  </span><br></pre></td></tr></table></figure>

<p>这里，identity既是减少的初始种子值，也是没有输入元素的默认结果。accumulator函数获得部分结果和下一个元素，并产生新的部分结果。combiner组合两个部分结果以产生新的部分结果。（组合器在并行归约中是必需的，其中输入被分割，为每个分区计算的部分累加，然后组合部分结果以产生最终结果。）</p>
<p>更正式地， identity值必须是组合器功能的标识。这意味着，对于所有u，combiner.apply(identity,  u)等于u 。此外，combiner功能必须是associative，并必须兼容accumulator功能：对所有u和t，combiner.apply(u, accumulator.apply(identity,  t))与accumulator.apply(u, t)的equals()结果必须为true。</p>
<p>三参数形式是双参数形式的泛化，将映射步骤纳入积累步骤。我们可以使用更一般的形式重写简单的权重示例，如下所示：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sumOfWeights</span> <span class="operator">=</span> widgets.stream().reduce(<span class="number">0</span>, (sum, b) -&gt; sum + b.getWeight()), Integer::sum);</span><br></pre></td></tr></table></figure>

<p>显式的<code>map-reduce</code>形式更具有可读性，因此通常应该是首选。为可以通过将映射和归约组合成单个函数来优化大量工作的情况提供了通用形式。。</p>
<h2 id="可变归约"><a href="#可变归约" class="headerlink" title="可变归约"></a>可变归约</h2><p><strong>可变归约操作</strong>将输入元素累加到可变结果容器中，例如Collection或StringBuilder，因为它处理流中的元素。</p>
<p>如果我们想采取一串字符串并将它们连接成一个长的字符串，我们可以通过普通的reduction实现这一点：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">String</span> <span class="variable">concatenated</span> <span class="operator">=</span> strings.reduce(<span class="string">&quot;&quot;</span>, String::concat)  </span><br></pre></td></tr></table></figure>

<p>我们会得到所需的结果，甚至可以并行工作。但是，我们可能不会对示例感到高兴！这样的实现将执行大量的字符串复制，并且运行时间将是字符数为O(n^2) 。更有效的方法是将结果累积到一个StringBuilder，它是一个用于累积字符串的可变容器。我们可以使用相同的技术并行化可变减少，就像我们用普通的减少一样。</p>
<p>可变归约操作称为collect() ，因为它将所需结果汇总到结果容器（如Collection。一个collect操作需要三个功能：供应商功能构造结果容器的新实例，将输入元素合并到结果容器中的累加器函数，以及将一个结果容器的内容合并到另一个中的组合函数。 这种形式与普通缩减的一般形式非常相似：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;R&gt; R <span class="title function_">collect</span><span class="params">(Supplier&lt;R&gt; supplier, BiConsumer&lt;R, ? <span class="built_in">super</span> T&gt; accumulator, BiConsumer&lt;R, R&gt; combiner)</span>;  </span><br></pre></td></tr></table></figure>

<p>与reduce()以抽象的方式表达collect的好处是可以直接适应并行化：只要积累和组合函数满足适当的要求，我们可以并行累积部分结果，然后将它们组合起来。例如，要将流中的元素的String表示形式收集到一个ArrayList，我们可以为每个形式写出明显的顺序：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">ArrayList&lt;String&gt; strings = <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line"><span class="keyword">for</span> (T element : stream) &#123; </span><br><span class="line">    strings.add(element.toString()); </span><br><span class="line">&#125;  </span><br></pre></td></tr></table></figure>

<p>或者我们可以使用可并行化的收集表单：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ArrayList&lt;String&gt; strings = stream.collect(() -&gt; <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;(), (c, e) -&gt; c.add(e.toString()), (c1, c2) -&gt; c1.addAll(c2));  </span><br></pre></td></tr></table></figure>

<p>或者将绘图操作拉出累加器函数，我们可以更简洁地表达：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; strings = stream.map(Object::toString).collect(ArrayList::<span class="keyword">new</span>, ArrayList::add, ArrayList::addAll);  </span><br></pre></td></tr></table></figure>

<p>在这里，我们的供应商只是ArrayList constructor，累加器将一个字符串元素添加到一个ArrayList，组合器只需使用addAll将字符串从一个容器复制到另一个容器中。</p>
<p>collect- supplier、accumulator和combiner的三个方面紧密耦合。 我们可以使用Collector的抽象来捕获所有三个方面。 将字符串收集到List中的上述示例可以使用标准Collector：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">List&lt;String&gt; strings = stream.map(Object::toString).collect(Collectors.toList());  </span><br></pre></td></tr></table></figure>

<p>将可变减少包装到收集器中有另一个优点：可组合性。 <code>Collectors</code>类包含了一些收集器的预定义工厂，包括将一个收集器转换成另一个收集器的组合器。例如，假设我们有一个收集器来计算员工流量的总和，如下所示：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Collector&lt;Employee, ?, Integer&gt; summingSalaries = Collectors.summingInt(Employee::getSalary);  </span><br></pre></td></tr></table></figure>

<p>（该? 。对于第二类参数仅仅表明我们不关心这个收集器所使用的中间表示）如果我们想创造一个收藏家制表工资由部门的总和，我们可以重用summingSalaries使用groupingBy：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Map&lt;Department, Integer&gt; salariesByDept = employees.stream().collect(Collectors.groupingBy(Employee::getDepartment, summingSalaries));  </span><br></pre></td></tr></table></figure>

<p>与正常的归约操作一样，collect()操作只能在符合条件的情况下进行并行化。对于任何部分累积的结果，将其与空结果容器组合必须产生等效结果。也就是说，部分累加结果p即任何系列累加器和组合器的调用的结果，p必须等同于combiner.apply(p, supplier.get())。</p>
<p>此外，然而，计算是分裂的，它必须产生等效的结果。对于任何输入元素t1和t2 ，下面的计算中的结果r1和r2必须是等效的：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">A</span> <span class="variable">a1</span> <span class="operator">=</span> supplier.get(); </span><br><span class="line">accumulator.accept(a1, t1); </span><br><span class="line">accumulator.accept(a1, t2); </span><br><span class="line"><span class="type">R</span> <span class="variable">r1</span> <span class="operator">=</span> finisher.apply(a1); </span><br><span class="line"><span class="comment">// result without splitting </span></span><br><span class="line"><span class="type">A</span> <span class="variable">a2</span> <span class="operator">=</span> supplier.get(); </span><br><span class="line">accumulator.accept(a2, t1); </span><br><span class="line"><span class="type">A</span> <span class="variable">a3</span> <span class="operator">=</span> supplier.get(); </span><br><span class="line">accumulator.accept(a3, t2); </span><br><span class="line"><span class="type">R</span> <span class="variable">r2</span> <span class="operator">=</span> finisher.apply(combiner.apply(a2, a3)); </span><br><span class="line"><span class="comment">// result with splitting  </span></span><br></pre></td></tr></table></figure>

<p>这里，等效通常意味着根据Object.equals(Object) 。 但是在某些情况下，可以放松等价以解决顺序上的差异。</p>
<p>对于一些复杂的减少操作，例如一个collect() ，其产生Map，如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Map&lt;Buyer, List&lt;Transaction&gt;&gt; salesByBuyer = txns.parallelStream().collect(Collectors.groupingBy(Transaction::getBuyer));  </span><br></pre></td></tr></table></figure>

<p>实际上并行执行操作可能会适得其反。这是因为组合步骤（将一个Map合并成另一个按键）对于一些Map实现可能是昂贵的。</p>
<p>然而，假设在此减少中使用的结果容器是可同时修改的集合，例如ConcurrentHashMap。在这种情况下，累加器的并行调用实际上可以将它们的结果同时存入相同的共享结果容器中，从而无需组合器来合并不同的结果容器。 这可能会提高并行执行性能。 我们称之为<strong>并发减少</strong>。</p>
<p>Collector支持并发还原标有Collector.Characteristics.CONCURRENT特性。然而，并发收集也有缺点。如果多个线程将结果并入到共享容器中，则结果存入的顺序是非确定性的。 因此，只有对于正在处理的流的顺序不重要，并发减少才是可能的。在以下情况该Stream.collect(Collector)实施将只执行并发减少：</p>
<ul>
<li>并发流;</li>
<li>Collector具有Collector.Characteristics.CONCURRENT特征，</li>
<li>流是无序的，或者收集器具有Collector.Characteristics.UNORDERED的特征。</li>
</ul>
<p>可以使用BaseStream.unordered()方法确保流无序 。例如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Map&lt;Buyer, List&lt;Transaction&gt;&gt; salesByBuyer = txns.parallelStream().unordered().collect(groupingByConcurrent(Transaction::getBuyer));  </span><br></pre></td></tr></table></figure>

<p>其中Collectors.groupingByConcurrent(java.util.function.Function&lt;? super T, ? extends K&gt;)等同于groupingBy。</p>
<p>请注意，如果给定键的元素以它们在源中显示的顺序显示很重要，那么我们不能使用并发缩减，因为排序是并发插入的一种伤害。然后，我们将被限制为执行顺序减少或基于并行的并行还原。</p>
<h2 id="低级流构造器"><a href="#低级流构造器" class="headerlink" title="低级流构造器"></a>低级流构造器</h2><p>到目前为止，所有的流示例都使用了Collection.stream()或Arrays.stream的方法（Object[]）来获取流。这些承载流的方法是如何实现的？</p>
<p>StreamSupport类有许多用于创建流的低级方法，所有这些方法都使用某种形式的Spliterator。一个分离器是一个迭代器的并行模拟；它描述了一个（可能是无限的）元素集合，支持顺序推进、批量遍历，并将输入的一部分拆分到另一个可以并行处理的拆分器中。在最低级别，所有流都由分离器驱动。</p>
<p>在实现拆分器时有许多实现选择，几乎所有这些都是在实现的简单性和使用该拆分器的流的运行时性能之间进行权衡。创建拆分器最简单但性能最低的方法是使用Spliterators.spliteratorUnknownSize（java.util.iterator，int）从迭代器创建一个。虽然这样的拆分器可以工作，但它可能会提供较差的并行性能，因为我们已经丢失了大小信息（底层数据集有多大），并且受制于简单的拆分算法。</p>
<p>更高质量的拆分器将提供均衡且已知的大小拆分、准确的大小信息以及拆分器的许多其他特性或数据，这些特性或数据可由实现用于优化执行。</p>
<p>用于可变数据源的分裂器还有一个额外的挑战；绑定到数据的时间，因为数据可能在创建分离器和执行流管道之间发生变化。理想情况下，流的分离器将报告IMUTABLE或CONCURRENT的特性；如果没有，那应该是后期绑定。如果源无法直接提供推荐的分离器，则可以使用供应商间接提供分离器，并通过接受stream()版本的供应商构建流。只有在流管道的终端操作开始后，才能从供应商处获得分离器。</p>
<p>这些要求显著减少了流源的突变和流管道的执行之间的潜在干扰范围。基于具有所需特性的分离器的流，或使用基于供应商的工厂形式的流，在终端操作开始前不受数据源修改的影响（前提是流操作的行为参数满足不干扰和无状态的要求标准）。有关详细信息，请参见无干扰。</p>
<h1 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h1><h2 id="枚举"><a href="#枚举" class="headerlink" title="枚举"></a>枚举</h2><table>
<thead>
<tr>
<th><strong>Enum</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Collector.Characteristics</td>
<td>指示Collector的属性的 Collector ，可用于优化collect实现。</td>
</tr>
</tbody></table>
<h3 id="枚举常量"><a href="#枚举常量" class="headerlink" title="枚举常量"></a>枚举常量</h3><ul>
<li>IDENTITY_FINISH：表示整理器功能是身份功能，可以被删除。</li>
<li>UNORDERED：表示收集操作不承诺保留输入元素的遇到顺序。</li>
<li>CONCURRENT：表示此收集器是<strong>并发的</strong>，这意味着结果容器可以支持与多个线程相同的结果容器同时调用的累加器函数。</li>
</ul>
<h3 id="所有方法"><a href="#所有方法" class="headerlink" title="所有方法"></a>所有方法</h3><table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>static Collector.Characteristics</td>
<td>valueOf(String name)</td>
<td>以指定的名称返回此类型的枚举常量。</td>
</tr>
<tr>
<td>static Collector.Characteristics[]</td>
<td>values()</td>
<td>按照它们声明的顺序返回一个包含此枚举类型常量的数组。</td>
</tr>
</tbody></table>
<h2 id="接口"><a href="#接口" class="headerlink" title="接口"></a>接口</h2><table>
<thead>
<tr>
<th><strong>接口</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>BaseStream&lt;T,S extends BaseStream&lt;T,S&gt;&gt;</td>
<td>流的基本界面，它们是支持顺序和并行聚合操作的元素序列。</td>
</tr>
<tr>
<td>Collector&lt;T,A,R&gt;</td>
<td>A mutable reduction operation将输入元素累加到可变结果容器中，可选地在所有输入元素被处理之后将累积结果转换成最终表示。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>支持顺序和并行聚合操作的原始双值元素序列。</td>
</tr>
<tr>
<td>DoubleStream.Builder</td>
<td>DoubleStream可变构建器。</td>
</tr>
<tr>
<td>IntStream</td>
<td>支持顺序和并行聚合操作的原始int值元素序列。</td>
</tr>
<tr>
<td>IntStream.Builder</td>
<td>IntStream可变构建器。</td>
</tr>
<tr>
<td>LongStream</td>
<td>支持顺序和并行聚合操作的原始长值元素序列。</td>
</tr>
<tr>
<td>LongStream.Builder</td>
<td>LongStream可变构建器。</td>
</tr>
<tr>
<td>Stream<T></td>
<td>支持顺序和并行聚合操作的一系列元素。</td>
</tr>
<tr>
<td>Stream.Builder<T></td>
<td>Stream可变构建器。</td>
</tr>
</tbody></table>
<h2 id="实现类"><a href="#实现类" class="headerlink" title="实现类"></a>实现类</h2><table>
<thead>
<tr>
<th><strong>类</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>Collectors</td>
<td>Collector的实现 ，实现各种有用的collect操作，例如将元素累积到集合中，根据各种标准汇总元素等。</td>
</tr>
<tr>
<td>StreamSupport</td>
<td>用于创建和操纵流的低级实用程序方法。</td>
</tr>
</tbody></table>
<h1 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h1><h2 id="接口-1"><a href="#接口-1" class="headerlink" title="接口"></a>接口</h2><h3 id="BaseStream"><a href="#BaseStream" class="headerlink" title="BaseStream"></a>BaseStream</h3><p>查看Stream的类图：</p>
<p><img src="https://ws9w6gsz7m.feishu.cn/space/api/box/stream/download/asynccode/?code=OTI3OWM1MGYwMjAxOGU2ODRiMWNjMTQ1MWE2N2U0OTFfaEx2T012d0hpM1YyVzFTRHJIaU1EWWQ2U0ZFVXdtTVhfVG9rZW46SWJWVmJ3WjNyb3FyOHh4SGF2UGNDVzZ0bjRkXzE2ODMwNDIwMTc6MTY4MzA0NTYxN19WNA" alt="img"></p>
<p>BaseStream是Stream的父类，提供了一些基础功能，包括：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>void</td>
<td>close()</td>
<td>关闭此流，导致此流管道的所有关闭处理程序被调用。</td>
</tr>
<tr>
<td>boolean</td>
<td>isParallel()</td>
<td>返回此流是否要执行终端操作，将并行执行。</td>
</tr>
<tr>
<td>Iterator<T></td>
<td>iterator()</td>
<td>返回此流的元素的迭代器。</td>
</tr>
<tr>
<td>S</td>
<td>onClose(Runnable closeHandler)</td>
<td>返回带有附加关闭处理程序的等效流。</td>
</tr>
<tr>
<td>S</td>
<td>parallel()</td>
<td>返回并行的等效流。</td>
</tr>
<tr>
<td>S</td>
<td>sequential()</td>
<td>返回顺序的等效流。</td>
</tr>
<tr>
<td>Spliterator<T></td>
<td>spliterator()</td>
<td>返回此流的元素的拼接器。</td>
</tr>
<tr>
<td>S</td>
<td>unordered()</td>
<td>返回等效的流，即 unordered 。</td>
</tr>
</tbody></table>
<p>AutoCloseable是BaseStream的父类，它只有一个方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>void</td>
<td>close()</td>
<td>关闭此资源，放弃任何潜在资源。</td>
</tr>
</tbody></table>
<p>AutoCloseable对象的close()方法在退出已在资源规范头中声明对象的try-with-resources块时自动调用。这种结构确保迅速释放，避免资源耗尽异常和可能发生的错误。</p>
<p>实际上，基类实现自动关闭是可能的，实际上是可行的，尽管不是所有的子类或实例都将保存可释放的资源。对于必须以完全一般性操作的代码，或者当知道AutoCloseable实例需要资源释放时，建议使用try资源结构。然而，使用设施，例如当Stream同时支持I&#x2F;O基和非I&#x2F;O基的形式，try-with-resources块是一般不必要使用非I&#x2F;O形式。</p>
<p>测试使用：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test1</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试isParallel()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">p1</span> <span class="operator">=</span> userList.stream().isParallel();</span><br><span class="line">    System.out.println(<span class="string">&quot;是否为并行流：&quot;</span> + p1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试parallel()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">p2</span> <span class="operator">=</span> userList.stream().parallel().isParallel();</span><br><span class="line">    System.out.println(<span class="string">&quot;是否为并行流：&quot;</span> + p2);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sequential()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">p3</span> <span class="operator">=</span> userList.parallelStream().sequential().isParallel();</span><br><span class="line">    System.out.println(<span class="string">&quot;是否为并行流：&quot;</span> + p3);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterator()方法</span></span><br><span class="line">    Iterator&lt;User&gt; iterator = userList.stream().iterator();</span><br><span class="line">    <span class="keyword">while</span> (iterator.hasNext())&#123;</span><br><span class="line">        System.out.println(iterator.next());</span><br><span class="line">    &#125;</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试onClose()方法</span></span><br><span class="line">    userList.stream().onClose(<span class="keyword">new</span> <span class="title class_">Runnable</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> &#123;</span><br><span class="line">            System.out.println(<span class="string">&quot;我被关闭了&quot;</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).close();</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试spliterator()方法，更多Spliterator用法请参考jdk文档</span></span><br><span class="line">    System.out.println(<span class="string">&quot;使用Spliterator遍历对象：&quot;</span>);</span><br><span class="line">    Spliterator&lt;User&gt; spliterator = userList.stream().spliterator();</span><br><span class="line">    spliterator.forEachRemaining(<span class="keyword">new</span> <span class="title class_">Consumer</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            System.out.println(user);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">是否为并行流：false</span><br><span class="line">-----------------------</span><br><span class="line">是否为并行流：true</span><br><span class="line">-----------------------</span><br><span class="line">是否为并行流：false</span><br><span class="line">-----------------------</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=28, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=32, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=21, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">-----------------------</span><br><span class="line">我被关闭了</span><br><span class="line">-----------------------</span><br><span class="line">使用Spliterator遍历对象：</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=28, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=32, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=21, height=162.0, weight=70.0, username=zhangsan)</span><br></pre></td></tr></table></figure>

<p>查看unordered()源码，这里实现为ReferencePipeline类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> Stream&lt;P_OUT&gt; <span class="title function_">unordered</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="comment">// 如果本身是无序的直接返回</span></span><br><span class="line">    <span class="keyword">if</span> (!isOrdered())</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">this</span>;</span><br><span class="line">    <span class="comment">// 添加一个无状态的操作，将流状态更改为StreamOpFlag.NOT_ORDERED</span></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">StatelessOp</span>&lt;P_OUT, P_OUT&gt;(<span class="built_in">this</span>, StreamShape.REFERENCE, StreamOpFlag.NOT_ORDERED) &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        Sink&lt;P_OUT&gt; <span class="title function_">opWrapSink</span><span class="params">(<span class="type">int</span> flags, Sink&lt;P_OUT&gt; sink)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> sink;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="Collector"><a href="#Collector" class="headerlink" title="Collector"></a>Collector</h3><p>A mutable reduction operation将输入元素累加到可变结果容器中，可选地在所有输入元素被处理之后将累加结果转换成最终表示。还原操作可以顺序还是并行执行。</p>
<p>A mutable reduction operation的示例包括：将元素累加到一个Collection;  使用连接字符串StringBuilder；计算诸如sum，min，max或average之类的元素的摘要信息；计算“枢纽表”摘要，如“卖方最大价值交易”等。Collectors类提供了许多常见的可变减少的实现。</p>
<ul>
<li>一个Collector由四个函数来指定，这四个函数一起工作以将条目累加到可变结果容器中，并且可选地对结果进行最终转换。他们是：<ul>
<li>创建新的结果容器（<code>supplier()</code>）</li>
<li>将新的数据元素并入结果容器（<code>accumulator()</code>）</li>
<li>将两个结果容器组合成一个（<code>combiner()</code>）</li>
<li>在容器上执行可选的最终变换（<code>finisher()</code>）</li>
</ul>
</li>
<li>收集者还具有一系列特征，如<code>Collector.Characteristics.CONCURRENT</code>，它提供了可以通过减少实现来提供更好性能的提示。</li>
</ul>
<p>Collector有以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>BiConsumer&lt;A,T&gt;</td>
<td>accumulator()</td>
<td>将值折叠成可变结果容器的函数。</td>
</tr>
<tr>
<td>Set&lt;Collector.Characteristics&gt;</td>
<td>characteristics()</td>
<td>返回一个Set的Collector.Characteristics表示该Collector的特征</td>
</tr>
<tr>
<td>BinaryOperator<A></td>
<td>combiner()</td>
<td>一个接受两个部分结果并将其合并的函数。</td>
</tr>
<tr>
<td>Function&lt;A,R&gt;</td>
<td>finisher()</td>
<td>执行从中间累积类型 A到最终结果类型 R的最终 R 。</td>
</tr>
<tr>
<td>static &lt;T,A,R&gt; Collector&lt;T,A,R&gt;</td>
<td>of(Supplier<A> supplier, BiConsumer&lt;A,T&gt; accumulator, BinaryOperator<A> combiner, Function&lt;A,R&gt; finisher, Collector.Characteristics… characteristics)</td>
<td>返回一个新Collector由给定的描述 supplier ， accumulator ， combiner和 finisher功能。</td>
</tr>
<tr>
<td>static &lt;T,R&gt; Collector&lt;T,R,R&gt;</td>
<td>of(Supplier<R> supplier, BiConsumer&lt;R,T&gt; accumulator, BinaryOperator<R> combiner, Collector.Characteristics… characteristics)</td>
<td>返回一个新 Collector由给定的描述 supplier ， accumulator和 combiner功能。</td>
</tr>
<tr>
<td>Supplier<A></td>
<td>supplier()</td>
<td>一个创建并返回一个新的可变结果容器的函数。</td>
</tr>
</tbody></table>
<p>Collector接口只有一个实现java.util.stream.Collectors.CollectorImpl，CollectorImpl是Collectors的静态内部类：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">static</span> <span class="keyword">class</span> <span class="title class_">CollectorImpl</span>&lt;T, A, R&gt; <span class="keyword">implements</span> <span class="title class_">Collector</span>&lt;T, A, R&gt; &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> Supplier&lt;A&gt; supplier;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> BiConsumer&lt;A, T&gt; accumulator;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> BinaryOperator&lt;A&gt; combiner;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> Function&lt;A, R&gt; finisher;</span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">final</span> Set&lt;Characteristics&gt; characteristics;</span><br><span class="line"></span><br><span class="line">    CollectorImpl(Supplier&lt;A&gt; supplier,</span><br><span class="line">                  BiConsumer&lt;A, T&gt; accumulator,</span><br><span class="line">                  BinaryOperator&lt;A&gt; combiner,</span><br><span class="line">                  Function&lt;A,R&gt; finisher,</span><br><span class="line">                  Set&lt;Characteristics&gt; characteristics) &#123;</span><br><span class="line">        <span class="built_in">this</span>.supplier = supplier;</span><br><span class="line">        <span class="built_in">this</span>.accumulator = accumulator;</span><br><span class="line">        <span class="built_in">this</span>.combiner = combiner;</span><br><span class="line">        <span class="built_in">this</span>.finisher = finisher;</span><br><span class="line">        <span class="built_in">this</span>.characteristics = characteristics;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    CollectorImpl(Supplier&lt;A&gt; supplier,</span><br><span class="line">                  BiConsumer&lt;A, T&gt; accumulator,</span><br><span class="line">                  BinaryOperator&lt;A&gt; combiner,</span><br><span class="line">                  Set&lt;Characteristics&gt; characteristics) &#123;</span><br><span class="line">        <span class="built_in">this</span>(supplier, accumulator, combiner, castingIdentity(), characteristics);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> BiConsumer&lt;A, T&gt; <span class="title function_">accumulator</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> accumulator;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Supplier&lt;A&gt; <span class="title function_">supplier</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> supplier;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> BinaryOperator&lt;A&gt; <span class="title function_">combiner</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> combiner;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Function&lt;A, R&gt; <span class="title function_">finisher</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> finisher;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="keyword">public</span> Set&lt;Characteristics&gt; <span class="title function_">characteristics</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> characteristics;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Collectors的大部分方法都是依赖CollectorImpl实现的，例如：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test2</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 将所有姓名拼接在一起</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">collect</span> <span class="operator">=</span> userList.stream().map(User::getUsername).collect(Collectors.joining());</span><br><span class="line">    System.out.println(collect);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">zhangsanlisiwangwuzhangsan</span><br></pre></td></tr></table></figure>

<p>查看Collectors的joining()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> Collector&lt;CharSequence, ?, String&gt; joining() &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">CollectorImpl</span>&lt;CharSequence, StringBuilder, String&gt;(</span><br><span class="line">            StringBuilder::<span class="keyword">new</span>, StringBuilder::append,</span><br><span class="line">            (r1, r2) -&gt; &#123; r1.append(r2); <span class="keyword">return</span> r1; &#125;,</span><br><span class="line">            StringBuilder::toString, CH_NOID);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>实际上就是创建了一个CollectorImpl示例，实现了</p>
<ol>
<li>supplier</li>
<li>accumulator</li>
<li>combiner</li>
<li>finisher</li>
</ol>
<p>等方法，并传入了characteristics。</p>
<p>Stream类提供另一个重载的collect方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&lt;R&gt; R <span class="title function_">collect</span><span class="params">(Supplier&lt;R&gt; supplier,</span></span><br><span class="line"><span class="params">              BiConsumer&lt;R, ? <span class="built_in">super</span> T&gt; accumulator,</span></span><br><span class="line"><span class="params">              BiConsumer&lt;R, R&gt; combiner)</span>;</span><br></pre></td></tr></table></figure>

<p>我们可以自己实现一个将姓名放在一个集合中的功能：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test2</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    Supplier&lt;List&lt;String&gt;&gt; supplier = <span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;List&lt;String&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> List&lt;String&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    BiConsumer&lt;List&lt;String&gt;, User&gt; accumulator = <span class="keyword">new</span> <span class="title class_">BiConsumer</span>&lt;List&lt;String&gt;, User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;String&gt; list, User user)</span> &#123;</span><br><span class="line">            list.add(user.getUsername());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    BiConsumer&lt;List&lt;String&gt;, List&lt;String&gt;&gt; combiner = <span class="keyword">new</span> <span class="title class_">BiConsumer</span>&lt;List&lt;String&gt;, List&lt;String&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;String&gt; list1, List&lt;String&gt; list2)</span> &#123;</span><br><span class="line">            list1.addAll(list2);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    List&lt;String&gt; collect1 = userList.stream().collect(supplier, accumulator, combiner);</span><br><span class="line">    System.out.println(collect1);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[zhangsan, lisi, wangwu, zhangsan]</span><br></pre></td></tr></table></figure>

<p>Collector还提供两个of函数，根据不同入参返回新Collector，最终返回的实现也是CollectorImpl。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span>&lt;T, R&gt; Collector&lt;T, R, R&gt; <span class="title function_">of</span><span class="params">(Supplier&lt;R&gt; supplier,</span></span><br><span class="line"><span class="params">                                          BiConsumer&lt;R, T&gt; accumulator,</span></span><br><span class="line"><span class="params">                                          BinaryOperator&lt;R&gt; combiner,</span></span><br><span class="line"><span class="params">                                          Characteristics... characteristics)</span> &#123;</span><br><span class="line">    Objects.requireNonNull(supplier);</span><br><span class="line">    Objects.requireNonNull(accumulator);</span><br><span class="line">    Objects.requireNonNull(combiner);</span><br><span class="line">    Objects.requireNonNull(characteristics);</span><br><span class="line">    Set&lt;Characteristics&gt; cs = (characteristics.length == <span class="number">0</span>)</span><br><span class="line">                              ? Collectors.CH_ID</span><br><span class="line">                              : Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.IDENTITY_FINISH,</span><br><span class="line">                                                                       characteristics));</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Collectors</span>.CollectorImpl&lt;&gt;(supplier, accumulator, combiner, cs);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span>&lt;T, A, R&gt; Collector&lt;T, A, R&gt; <span class="title function_">of</span><span class="params">(Supplier&lt;A&gt; supplier,</span></span><br><span class="line"><span class="params">                                             BiConsumer&lt;A, T&gt; accumulator,</span></span><br><span class="line"><span class="params">                                             BinaryOperator&lt;A&gt; combiner,</span></span><br><span class="line"><span class="params">                                             Function&lt;A, R&gt; finisher,</span></span><br><span class="line"><span class="params">                                             Characteristics... characteristics)</span> &#123;</span><br><span class="line">    Objects.requireNonNull(supplier);</span><br><span class="line">    Objects.requireNonNull(accumulator);</span><br><span class="line">    Objects.requireNonNull(combiner);</span><br><span class="line">    Objects.requireNonNull(finisher);</span><br><span class="line">    Objects.requireNonNull(characteristics);</span><br><span class="line">    Set&lt;Characteristics&gt; cs = Collectors.CH_NOID;</span><br><span class="line">    <span class="keyword">if</span> (characteristics.length &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        cs = EnumSet.noneOf(Characteristics.class);</span><br><span class="line">        Collections.addAll(cs, characteristics);</span><br><span class="line">        cs = Collections.unmodifiableSet(cs);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Collectors</span>.CollectorImpl&lt;&gt;(supplier, accumulator, combiner, finisher, cs);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="DoubleStream"><a href="#DoubleStream" class="headerlink" title="DoubleStream"></a>DoubleStream</h3><p>DoubleStream支持顺序和并行聚合操作的原始双值元素序列，是double原始专长Stream。</p>
<p>DoubleStream有以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>boolean</td>
<td>allMatch(DoublePredicate predicate)</td>
<td>返回此流的所有元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>boolean</td>
<td>anyMatch(DoublePredicate predicate)</td>
<td>返回此流的任何元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>average()</td>
<td>返回 OptionalDouble此流的元素的算术平均值的OptionalDouble，如果此流为空，则返回一个空的可选项。</td>
</tr>
<tr>
<td>Stream<Double></td>
<td>boxed()</td>
<td>返回一个 Stream组成的这个流的元素，装箱到 Double 。</td>
</tr>
<tr>
<td>static DoubleStream.Builder</td>
<td>builder()</td>
<td>返回一个 DoubleStream的生成器。</td>
</tr>
<tr>
<td><R> R</td>
<td>collect(Supplier<R> supplier, ObjDoubleConsumer<R> accumulator, BiConsumer&lt;R,R&gt; combiner)</td>
<td>对此流的元素执行 mutable reduction操作。</td>
</tr>
<tr>
<td>static DoubleStream</td>
<td>concat(DoubleStream a, DoubleStream b)</td>
<td>创建一个懒惰连接的流，其元素是第一个流的所有元素，后跟第二个流的所有元素。</td>
</tr>
<tr>
<td>long</td>
<td>count()</td>
<td>返回此流中的元素数。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>distinct()</td>
<td>返回由该流的不同元素组成的流。</td>
</tr>
<tr>
<td>static DoubleStream</td>
<td>empty()</td>
<td>返回一个空的顺序 DoubleStream 。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>filter(DoublePredicate predicate)</td>
<td>返回由与此给定谓词匹配的此流的元素组成的流。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>findAny()</td>
<td>返回描述流的一些元素的OptionalDouble如果流为空，则返回一个空的OptionalDouble 。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>findFirst()</td>
<td>返回描述此流的第一个元素的OptionalDouble如果流为空，则返回一个空的OptionalDouble 。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>flatMap(DoubleFunction&lt;? extends DoubleStream&gt; mapper)</td>
<td>返回由通过将提供的映射函数应用于每个元素而产生的映射流的内容来替换该流的每个元素的结果的流。</td>
</tr>
<tr>
<td>void</td>
<td>forEach(DoubleConsumer action)</td>
<td>对此流的每个元素执行操作。</td>
</tr>
<tr>
<td>void</td>
<td>forEachOrdered(DoubleConsumer action)</td>
<td>对此流的每个元素执行一个操作，保证每个元素按遇到顺序处理，以便具有定义的遇到顺序的流。</td>
</tr>
<tr>
<td>static DoubleStream</td>
<td>generate(DoubleSupplier s)</td>
<td>返回无限顺序无序流，其中每个元素由提供的 DoubleSupplier 。</td>
</tr>
<tr>
<td>static DoubleStream</td>
<td>iterate(double seed, DoubleUnaryOperator f)</td>
<td>返回有序无限连续 DoubleStream由函数的迭代应用产生 f至初始元素 seed ，产生 Stream包括 seed ， f(seed) ， f(f(seed)) ，等</td>
</tr>
<tr>
<td>PrimitiveIterator.OfDouble</td>
<td>iterator()</td>
<td>返回此流的元素的迭代器。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>limit(long maxSize)</td>
<td>返回由此流的元素组成的流，截断长度不能超过 maxSize。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>map(DoubleUnaryOperator mapper)</td>
<td>返回由给定函数应用于此流的元素的结果组成的流。</td>
</tr>
<tr>
<td>IntStream</td>
<td>mapToInt(DoubleToIntFunction mapper)</td>
<td>返回一个 IntStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>LongStream</td>
<td>mapToLong(DoubleToLongFunction mapper)</td>
<td>返回一个 LongStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td><U> Stream<U></td>
<td>mapToObj(DoubleFunction&lt;? extends U&gt; mapper)</td>
<td>返回一个对象值 Stream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>max()</td>
<td>返回 OptionalDouble此流的最大元素的OptionalDouble，如果此流为空，则返回空的OptionalDouble。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>min()</td>
<td>返回 OptionalDouble此流的最小元素的OptionalDouble，如果此流为空，则返回空的OptionalDouble。</td>
</tr>
<tr>
<td>boolean</td>
<td>noneMatch(DoublePredicate predicate)</td>
<td>返回此流的元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>static DoubleStream</td>
<td>of(double… values)</td>
<td>返回其元素是指定值的顺序排序流。</td>
</tr>
<tr>
<td>static DoubleStream</td>
<td>of(double t)</td>
<td>返回包含单个元素的顺序 DoubleStream 。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>parallel()</td>
<td>返回平行的等效流。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>peek(DoubleConsumer action)</td>
<td>返回由该流的元素组成的流，另外在从生成的流中消耗元素时对每个元素执行提供的操作。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>reduce(DoubleBinaryOperator op)</td>
<td>使用 associative累积函数对此流的元素执行 reduction ，并返回描述减小值（如果有的话）的 OptionalDouble 。</td>
</tr>
<tr>
<td>double</td>
<td>reduce(double identity, DoubleBinaryOperator op)</td>
<td>使用提供的身份值和 associative累积功能对此流的元素执行 reduction ，并返回减小的值。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>sequential()</td>
<td>返回顺序的等效流。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>skip(long n)</td>
<td>在丢弃流的第一个 n元素之后，返回由该流的 n元素组成的流。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>sorted()</td>
<td>以排序顺序返回由该流的元素组成的流。</td>
</tr>
<tr>
<td>Spliterator.OfDouble</td>
<td>spliterator()</td>
<td>返回此流的元素的拼接器。</td>
</tr>
<tr>
<td>double</td>
<td>sum()</td>
<td>返回此流中元素的总和。</td>
</tr>
<tr>
<td>DoubleSummaryStatistics</td>
<td>summaryStatistics()</td>
<td>返回一个 DoubleSummaryStatistics描述有关此流的元素的各种摘要数据。</td>
</tr>
<tr>
<td>double[]</td>
<td>toArray()</td>
<td>返回一个包含此流的元素的数组。</td>
</tr>
</tbody></table>
<p>我们可以生成一个DoubleStream：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">DoubleStream</span> <span class="variable">doubleStream</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getHeight);</span><br></pre></td></tr></table></figure>

<p>查看mapToDouble()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">final</span> DoubleStream <span class="title function_">mapToDouble</span><span class="params">(ToDoubleFunction&lt;? <span class="built_in">super</span> P_OUT&gt; mapper)</span> &#123;</span><br><span class="line">    Objects.requireNonNull(mapper);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">DoublePipeline</span>.StatelessOp&lt;P_OUT&gt;(<span class="built_in">this</span>, StreamShape.REFERENCE,</span><br><span class="line">                                    StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        Sink&lt;P_OUT&gt; <span class="title function_">opWrapSink</span><span class="params">(<span class="type">int</span> flags, Sink&lt;Double&gt; sink)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Sink</span>.ChainedReference&lt;P_OUT, Double&gt;(sink) &#123;</span><br><span class="line">                <span class="meta">@Override</span></span><br><span class="line">                <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(P_OUT u)</span> &#123;</span><br><span class="line">                    downstream.accept(mapper.applyAsDouble(u));</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>实际返回的是一个StatelessOp类型，查看其类图：</p>
<p><img src="https://ws9w6gsz7m.feishu.cn/space/api/box/stream/download/asynccode/?code=MDMyOWJlZTNmN2I4ZmUyNGQwMWEwYzUzNWQwNzU2OWVfallIeWh1eDNwQ3kzeThta3BRT2NyRVJmUHJLWEw2bHBfVG9rZW46RW5VRWIzZWJ1b3lOT1N4bUFCNmNHZHpNblpkXzE2ODMwNDIwMTc6MTY4MzA0NTYxN19WNA" alt="img"></p>
<p>StatelessOp继承了DoubleStream，DoubleStream又继承了AbstractPipeline，其实AbstractPipeline有很多常用的实现，比如:</p>
<ol>
<li>Stream对应的实现ReferencePipeline</li>
<li>IntStream对应的实现IntPipeline</li>
<li>LongStream对应的实现IntPipeline</li>
</ol>
<p><img src="https://ws9w6gsz7m.feishu.cn/space/api/box/stream/download/asynccode/?code=ZTg1NjRmMTk4NWNiYTgxMjZhNTQxMjNjYjdlZDdiYjZfV0tEZXN6eTExYmZ5TGx0V3luVk4wVU5aMFl3am42U1pfVG9rZW46QW5vVmIwMUtMb0hhUE54eGROZWNDSTZqblVkXzE2ODMwNDIwMTc6MTY4MzA0NTYxN19WNA" alt="img"></p>
<p>也可以通过DoubleStream的静态方法of()来创建DoubleStream：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">DoubleStream</span> <span class="variable">doubleStream</span> <span class="operator">=</span> DoubleStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>);</span><br></pre></td></tr></table></figure>

<p>进入of()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> DoubleStream <span class="title function_">of</span><span class="params">(<span class="type">double</span>... values)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> Arrays.stream(values);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>进入Arrays.stream()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> DoubleStream <span class="title function_">stream</span><span class="params">(<span class="type">double</span>[] array)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> stream(array, <span class="number">0</span>, array.length);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>进入重载的stream()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> DoubleStream <span class="title function_">stream</span><span class="params">(<span class="type">double</span>[] array, <span class="type">int</span> startInclusive, <span class="type">int</span> endExclusive)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> StreamSupport.doubleStream(spliterator(array, startInclusive, endExclusive), <span class="literal">false</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>最终使用的是StreamSupport的doubleStream()创建DoubleStream，进入doubleStream()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> DoubleStream <span class="title function_">doubleStream</span><span class="params">(Spliterator.OfDouble spliterator,</span></span><br><span class="line"><span class="params">                                        <span class="type">boolean</span> parallel)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">DoublePipeline</span>.Head&lt;&gt;(spliterator,</span><br><span class="line">                                     StreamOpFlag.fromCharacteristics(spliterator),</span><br><span class="line">                                     parallel);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>新建了一个Head类，而Head又是DoublePipeline子类。</p>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test3</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试allMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">allMatch</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).allMatch(<span class="keyword">new</span> <span class="title class_">DoublePredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">double</span> age)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> age &lt; <span class="number">50</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否所有用户都小于50岁：&quot;</span> + allMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试anyMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">anyMatch</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).anyMatch(<span class="keyword">new</span> <span class="title class_">DoublePredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">double</span> age)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> age &lt; <span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否存在年龄小于10岁的用户：&quot;</span> + anyMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试average()方法</span></span><br><span class="line">    <span class="type">OptionalDouble</span> <span class="variable">average</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).average();</span><br><span class="line">    System.out.println(<span class="string">&quot;用户评价年龄为：&quot;</span> + average.orElse(-<span class="number">1</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试boxed()方法</span></span><br><span class="line">    Stream&lt;Double&gt; boxed = userList.stream().mapToDouble(User::getAge).boxed();</span><br><span class="line">    System.out.println(<span class="string">&quot;通过装箱的Stream统计数量：&quot;</span> + boxed.count());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    <span class="type">DoubleStream</span> <span class="variable">build1</span> <span class="operator">=</span> DoubleStream.builder().add(<span class="number">1</span>).add(<span class="number">2</span>).add(<span class="number">3</span>).build();</span><br><span class="line">    System.out.println(<span class="string">&quot;遍历通过builder()方法创建的DoubleStream元素：&quot;</span>);</span><br><span class="line">    build1.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试collect()方法</span></span><br><span class="line">    Supplier&lt;List&lt;Double&gt;&gt; supplier = <span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;List&lt;Double&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> List&lt;Double&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    ObjDoubleConsumer&lt;List&lt;Double&gt;&gt; accumulator = <span class="keyword">new</span> <span class="title class_">ObjDoubleConsumer</span>&lt;List&lt;Double&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;Double&gt; list, <span class="type">double</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (value &gt; <span class="number">20</span>) &#123;</span><br><span class="line">                list.add(value);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    BiConsumer&lt;List&lt;Double&gt;, List&lt;Double&gt;&gt; combiner = <span class="keyword">new</span> <span class="title class_">BiConsumer</span>&lt;List&lt;Double&gt;, List&lt;Double&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;Double&gt; list1, List&lt;Double&gt; list2)</span> &#123;</span><br><span class="line">            list1.addAll(list2);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    List&lt;Double&gt; collect = userList.stream()</span><br><span class="line">            .mapToDouble(User::getAge)</span><br><span class="line">            .collect(supplier, accumulator, combiner);</span><br><span class="line">    System.out.println(<span class="string">&quot;列举所有大于20的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(collect);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试concat()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印两个连接起来的DoubleStream元素：&quot;</span>);</span><br><span class="line">    DoubleStream.concat(userList.stream().mapToDouble(User::getAge), DoubleStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>)).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试count()方法</span></span><br><span class="line">    <span class="type">long</span> <span class="variable">count</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).count();</span><br><span class="line">    System.out.println(<span class="string">&quot;流中元素的总数：&quot;</span>);</span><br><span class="line">    System.out.println(count);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试distinct()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印去重后的年龄：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).distinct().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试empty()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;获取一个空的DoubleStream：&quot;</span>);</span><br><span class="line">    <span class="type">DoubleStream</span> <span class="variable">empty</span> <span class="operator">=</span> DoubleStream.empty();</span><br><span class="line">    System.out.println(empty);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试filter()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;过滤调年龄大于30的用户：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).filter(age -&gt; age &lt;= <span class="number">30</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findAny()方法，返回流中任意的一个元素并包装成OptionalDouble，结果不稳定</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">asDouble1</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).findAny().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中任意元素并包装成OptionalDouble：&quot;</span>);</span><br><span class="line">    System.out.println(asDouble1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findFirst()方法，返回流中第一个元素并包装成OptionalDouble，结果稳定</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">asDouble2</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).findFirst().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中首个元素并包装成OptionalDouble：&quot;</span>);</span><br><span class="line">    System.out.println(asDouble2);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试flatMap()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;测试flatMap()方法，每人年龄+10岁：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).flatMap(<span class="keyword">new</span> <span class="title class_">DoubleFunction</span>&lt;DoubleStream&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> DoubleStream <span class="title function_">apply</span><span class="params">(<span class="type">double</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> DoubleStream.of(value + <span class="number">10</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEach()方法，不保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().mapToDouble(User::getAge).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEachOrdered()方法，保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().mapToDouble(User::getAge).forEachOrdered(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试generate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;随机生成10个数字：&quot;</span>);</span><br><span class="line">    <span class="type">double</span>[] doubles = DoubleStream.generate(<span class="keyword">new</span> <span class="title class_">DoubleSupplier</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">getAsDouble</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> Math.random();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(doubles));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成10个等差数：&quot;</span>);</span><br><span class="line">    <span class="type">double</span>[] doubles1 = DoubleStream.iterate(<span class="number">2</span>, <span class="keyword">new</span> <span class="title class_">DoubleUnaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(<span class="type">double</span> operand)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> operand + <span class="number">2</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(doubles1));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    PrimitiveIterator.<span class="type">OfDouble</span> <span class="variable">iterator</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).iterator();</span><br><span class="line">    System.out.println(<span class="string">&quot;通过iterate打印元素：&quot;</span>);</span><br><span class="line">    <span class="keyword">while</span> (iterator.hasNext()) &#123;</span><br><span class="line">        System.out.println(iterator.next());</span><br><span class="line">    &#125;</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试limit()方法</span></span><br><span class="line">    <span class="type">OptionalDouble</span> <span class="variable">average1</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).limit(<span class="number">3</span>).average();</span><br><span class="line">    System.out.println(<span class="string">&quot;求前三个用户的平均年龄：&quot;</span>);</span><br><span class="line">    System.out.println(average1.orElse(-<span class="number">1</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试map()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄+20岁：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).map(<span class="keyword">new</span> <span class="title class_">DoubleUnaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(<span class="type">double</span> operand)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> operand + <span class="number">20</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToInt()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为整型：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).mapToInt(<span class="keyword">new</span> <span class="title class_">DoubleToIntFunction</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(<span class="type">double</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> (<span class="type">int</span>) value;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToLong()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为长整型：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).mapToLong(<span class="keyword">new</span> <span class="title class_">DoubleToLongFunction</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(<span class="type">double</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> (<span class="type">long</span>) value;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToObj()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为用户：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).mapToObj(<span class="keyword">new</span> <span class="title class_">DoubleFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(<span class="type">double</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> User.builder().age((<span class="type">int</span>) value).build();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试max()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">maxAge</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).max().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最大的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(maxAge);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试min()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">minAge</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).min().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最小的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(minAge);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试noneMatch()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回是否没有年龄大于100的用户：&quot;</span>);</span><br><span class="line">    <span class="type">boolean</span> <span class="variable">noneMatch</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).noneMatch(<span class="keyword">new</span> <span class="title class_">DoublePredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">double</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value &gt; <span class="number">100</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(noneMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的多个元素序列：&quot;</span>);</span><br><span class="line">    DoubleStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的单个元素序列：&quot;</span>);</span><br><span class="line">    DoubleStream.of(<span class="number">1</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试parallel()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回并发流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.stream().mapToDouble(User::getAge).parallel());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试peek()方法，是一个中间操作，主要用于调试</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印流中的每个元素：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).peek(<span class="keyword">new</span> <span class="title class_">DoubleConsumer</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(<span class="type">double</span> value)</span> &#123;</span><br><span class="line">            System.out.println(value);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).sum();</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为流的第一个元素</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    <span class="type">double</span> <span class="variable">v</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).reduce(<span class="keyword">new</span> <span class="title class_">DoubleBinaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(<span class="type">double</span> left, <span class="type">double</span> right)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> left + right;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(v);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为identity（即第一个参数）</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    <span class="type">double</span> <span class="variable">sum</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).reduce(<span class="number">0</span>, <span class="keyword">new</span> <span class="title class_">DoubleBinaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(<span class="type">double</span> left, <span class="type">double</span> right)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> left + right;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(sum);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sequential()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回顺序流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.parallelStream().mapToDouble(User::getAge).sequential());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试skip()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;跳过前三个元素：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).skip(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sorted()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;按年龄大小排序：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(User::getAge).sorted().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sum()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">sum1</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).sum();</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄总和：&quot;</span>);</span><br><span class="line">    System.out.println(sum1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summaryStatistics()方法，返回各种摘要信息</span></span><br><span class="line">    <span class="type">DoubleSummaryStatistics</span> <span class="variable">statistics</span> <span class="operator">=</span> userList.stream().mapToDouble(User::getAge).summaryStatistics();</span><br><span class="line">    System.out.println(<span class="string">&quot;和：&quot;</span> + statistics.getSum());</span><br><span class="line">    System.out.println(<span class="string">&quot;数量：&quot;</span> + statistics.getCount());</span><br><span class="line">    System.out.println(<span class="string">&quot;最大值：&quot;</span> + statistics.getMax());</span><br><span class="line">    System.out.println(<span class="string">&quot;最小值：&quot;</span> + statistics.getMin());</span><br><span class="line">    System.out.println(<span class="string">&quot;平均值：&quot;</span> + statistics.getAverage());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toArray()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;转换为double数组：&quot;</span>);</span><br><span class="line">    <span class="type">double</span>[] doubles2 = userList.stream().mapToDouble(User::getAge).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(doubles2));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br></pre></td><td class="code"><pre><span class="line">是否所有用户都小于50岁：true</span><br><span class="line">-----------------------</span><br><span class="line">是否存在年龄小于10岁的用户：false</span><br><span class="line">-----------------------</span><br><span class="line">用户评价年龄为：24.0</span><br><span class="line">-----------------------</span><br><span class="line">通过装箱的Stream统计数量：5</span><br><span class="line">-----------------------</span><br><span class="line">遍历通过builder()方法创建的DoubleStream元素：</span><br><span class="line">1.0</span><br><span class="line">2.0</span><br><span class="line">3.0</span><br><span class="line">-----------------------</span><br><span class="line">列举所有大于20的年龄：</span><br><span class="line">[28.0, 32.0, 21.0, 21.0]</span><br><span class="line">-----------------------</span><br><span class="line">打印两个连接起来的DoubleStream元素：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">1.0</span><br><span class="line">2.0</span><br><span class="line">3.0</span><br><span class="line">4.0</span><br><span class="line">5.0</span><br><span class="line">-----------------------</span><br><span class="line">流中元素的总数：</span><br><span class="line">5</span><br><span class="line">-----------------------</span><br><span class="line">打印去重后的年龄：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">获取一个空的DoubleStream：</span><br><span class="line">java.util.stream.DoublePipeline$Head@70177ecd</span><br><span class="line">-----------------------</span><br><span class="line">过滤调年龄大于30的用户：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">返回流中任意元素并包装成OptionalDouble：</span><br><span class="line">18.0</span><br><span class="line">-----------------------</span><br><span class="line">返回流中首个元素并包装成OptionalDouble：</span><br><span class="line">18.0</span><br><span class="line">-----------------------</span><br><span class="line">测试flatMap()方法，每人年龄+10岁：</span><br><span class="line">28.0</span><br><span class="line">38.0</span><br><span class="line">42.0</span><br><span class="line">31.0</span><br><span class="line">31.0</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">28.0</span><br><span class="line">18.0</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">随机生成10个数字：</span><br><span class="line">[0.18121932440868183, 0.904518798550446, 0.011759406143421747, 0.06724315355410238, 0.313646526209993, 0.2979765562818961, 0.3532403626941105, 0.7891910846750343, 0.8739355801002622, 0.030225708400019924]</span><br><span class="line">-----------------------</span><br><span class="line">生成10个等差数：</span><br><span class="line">[2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0]</span><br><span class="line">通过iterate打印元素：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">求前三个用户的平均年龄：</span><br><span class="line">26.0</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄+20岁：</span><br><span class="line">38.0</span><br><span class="line">48.0</span><br><span class="line">52.0</span><br><span class="line">41.0</span><br><span class="line">41.0</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为整型：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为长整型：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为用户：</span><br><span class="line">User(age=18, height=null, weight=null, username=null)</span><br><span class="line">User(age=28, height=null, weight=null, username=null)</span><br><span class="line">User(age=32, height=null, weight=null, username=null)</span><br><span class="line">User(age=21, height=null, weight=null, username=null)</span><br><span class="line">User(age=21, height=null, weight=null, username=null)</span><br><span class="line">-----------------------</span><br><span class="line">获取最大的年龄：</span><br><span class="line">32.0</span><br><span class="line">-----------------------</span><br><span class="line">获取最小的年龄：</span><br><span class="line">18.0</span><br><span class="line">-----------------------</span><br><span class="line">返回是否没有年龄大于100的用户：</span><br><span class="line">true</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的多个元素序列：</span><br><span class="line">1.0</span><br><span class="line">2.0</span><br><span class="line">3.0</span><br><span class="line">4.0</span><br><span class="line">5.0</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的单个元素序列：</span><br><span class="line">1.0</span><br><span class="line">-----------------------</span><br><span class="line">返回并发流：</span><br><span class="line">java.util.stream.ReferencePipeline$6@69d0a921</span><br><span class="line">-----------------------</span><br><span class="line">打印流中的每个元素：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">120.0</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">120.0</span><br><span class="line">-----------------------</span><br><span class="line">返回顺序流：</span><br><span class="line">java.util.stream.ReferencePipeline$6@42110406</span><br><span class="line">-----------------------</span><br><span class="line">跳过前三个元素：</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">按年龄大小排序：</span><br><span class="line">18.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">-----------------------</span><br><span class="line">求年龄总和：</span><br><span class="line">120.0</span><br><span class="line">-----------------------</span><br><span class="line">和：120.0</span><br><span class="line">数量：5</span><br><span class="line">最大值：32.0</span><br><span class="line">最小值：18.0</span><br><span class="line">平均值：24.0</span><br><span class="line">-----------------------</span><br><span class="line">转换为double数组：</span><br><span class="line">[18.0, 28.0, 32.0, 21.0, 21.0]</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<h3 id="DoubleStream-Builder"><a href="#DoubleStream-Builder" class="headerlink" title="DoubleStream.Builder"></a>DoubleStream.Builder</h3><p>DoubleStream.Builder是DoubleStream是构建器，DoubleStream.Builder具有生命周期，其从构建阶段开始，在该阶段期间可以添加元素，然后转换到内置阶段，之后可能不添加元素。构建阶段从调用build()方法开始，它创建一个有序流，其元素是添加到流构建器的元素，按照它们被添加的顺序。</p>
<p>DoubleStream.Builder提供以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>void</td>
<td>accept(double t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>default DoubleStream.Builder</td>
<td>add(double t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>build()</td>
<td>构建流，将此构建器转换为内置状态。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test4</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    <span class="type">DoubleStream</span> <span class="variable">build1</span> <span class="operator">=</span> DoubleStream.builder().add(<span class="number">1</span>).add(<span class="number">2</span>).add(<span class="number">3</span>).build();</span><br><span class="line">    System.out.println(<span class="string">&quot;遍历通过builder()方法创建的DoubleStream元素：&quot;</span>);</span><br><span class="line">    build1.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">遍历通过builder()方法创建的DoubleStream元素：</span><br><span class="line">1.0</span><br><span class="line">2.0</span><br><span class="line">3.0</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<p>DoubleStream.Builderd的accept(double t)方法只在DoubleStreamBuilderImpl中有实现，DoubleStreamBuilderImpl在两个地方有用法：</p>
<ol>
<li>DoubleStream的builder()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回DoubleStreamBuilderImpl实例</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> Builder <span class="title function_">builder</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Streams</span>.DoubleStreamBuilderImpl();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>DoubleStream的of()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回具有单个元素的DoubleStream </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> DoubleStream <span class="title function_">of</span><span class="params">(<span class="type">double</span> t)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> StreamSupport.doubleStream(<span class="keyword">new</span> <span class="title class_">Streams</span>.DoubleStreamBuilderImpl(t), <span class="literal">false</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="IntStream"><a href="#IntStream" class="headerlink" title="IntStream"></a>IntStream</h3><p>IntStream支持顺序和并行聚合操作的原始int值元素序列，是int原始专长Stream。</p>
<p>IntStream有以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>boolean</td>
<td>allMatch(IntPredicate predicate)</td>
<td>返回此流的所有元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>boolean</td>
<td>anyMatch(IntPredicate predicate)</td>
<td>返回此流的任何元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>asDoubleStream()</td>
<td>返回一个DoubleStream由该流中的元素，转换为double 。</td>
</tr>
<tr>
<td>LongStream</td>
<td>asLongStream()</td>
<td>返回一个LongStream由该流的元素组成，转换为long 。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>average()</td>
<td>返回OptionalDouble此流的元素的算术平均值的OptionalDouble，如果此流为空，则返回空的可选项。</td>
</tr>
<tr>
<td>Stream<Integer></td>
<td>boxed()</td>
<td>返回一个Stream组成的这个流的元素，每个盒装到一个Integer 。</td>
</tr>
<tr>
<td>static IntStream.Builder</td>
<td>builder()</td>
<td>返回一个IntStream的生成器。</td>
</tr>
<tr>
<td><R> R</td>
<td>collect(Supplier<R> supplier, ObjIntConsumer<R> accumulator, BiConsumer&lt;R,R&gt; combiner)</td>
<td>对此流的元素执行mutable reduction操作。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>concat(IntStream a, IntStream b)</td>
<td>创建一个懒惰连接的流，其元素是第一个流的所有元素，后跟第二个流的所有元素。</td>
</tr>
<tr>
<td>long</td>
<td>count()</td>
<td>返回此流中的元素数。</td>
</tr>
<tr>
<td>IntStream</td>
<td>distinct()</td>
<td>返回由该流的不同元素组成的流。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>empty()</td>
<td>返回一个空的顺序IntStream 。</td>
</tr>
<tr>
<td>IntStream</td>
<td>filter(IntPredicate predicate)</td>
<td>返回由与此给定谓词匹配的此流的元素组成的流。</td>
</tr>
<tr>
<td>OptionalInt</td>
<td>findAny()</td>
<td>返回一个描述流的一些元素的OptionalInt如果流为空，则返回一个空的OptionalInt 。</td>
</tr>
<tr>
<td>OptionalInt</td>
<td>findFirst()</td>
<td>返回描述此流的第一个元素的OptionalInt如果流为空，则返回一个空的OptionalInt 。</td>
</tr>
<tr>
<td>IntStream</td>
<td>flatMap(IntFunction&lt;? extends IntStream&gt; mapper)</td>
<td>返回由通过将提供的映射函数应用于每个元素而产生的映射流的内容来替换该流的每个元素的结果的流。</td>
</tr>
<tr>
<td>void</td>
<td>forEach(IntConsumer action)</td>
<td>对此流的每个元素执行操作。</td>
</tr>
<tr>
<td>void</td>
<td>forEachOrdered(IntConsumer action)</td>
<td>对此流的每个元素执行一个操作，保证每个元素按遇到顺序处理，以便具有定义的遇到顺序的流。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>generate(IntSupplier s)</td>
<td>返回无限顺序无序流，其中每个元素由提供的IntSupplier。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>iterate(int seed, IntUnaryOperator f)</td>
<td>返回有序无限连续IntStream由函数的迭代应用产生f至初始元素seed ，产生 Stream包括 seed ， f(seed) ， f(f(seed)) ，等</td>
</tr>
<tr>
<td>PrimitiveIterator.OfInt</td>
<td>iterator()</td>
<td>返回此流的元素的迭代器。</td>
</tr>
<tr>
<td>IntStream</td>
<td>limit(long maxSize)</td>
<td>返回由此流的元素组成的流，截断长度不能超过 maxSize 。</td>
</tr>
<tr>
<td>IntStream</td>
<td>map(IntUnaryOperator mapper)</td>
<td>返回由给定函数应用于此流的元素的结果组成的流。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>mapToDouble(IntToDoubleFunction mapper)</td>
<td>返回一个 DoubleStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>LongStream</td>
<td>mapToLong(IntToLongFunction mapper)</td>
<td>返回一个 LongStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td><U> Stream<U></td>
<td>mapToObj(IntFunction&lt;? extends U&gt; mapper)</td>
<td>返回一个对象值 Stream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>OptionalInt</td>
<td>max()</td>
<td>返回 OptionalInt此流的最大元素的OptionalInt，如果此流为空，则返回一个空的可选项。</td>
</tr>
<tr>
<td>OptionalInt</td>
<td>min()</td>
<td>返回 OptionalInt此流的最小元素的OptionalInt，如果此流为空，则返回一个空的可选项。</td>
</tr>
<tr>
<td>boolean</td>
<td>noneMatch(IntPredicate predicate)</td>
<td>返回此流的元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>of(int… values)</td>
<td>返回其元素是指定值的顺序排序流。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>of(int t)</td>
<td>返回一个包含单个元素的顺序IntStream。</td>
</tr>
<tr>
<td>IntStream</td>
<td>parallel()</td>
<td>返回平行的等效流。</td>
</tr>
<tr>
<td>IntStream</td>
<td>peek(IntConsumer action)</td>
<td>返回由该流的元素组成的流，另外在从生成的流中消耗元素时对每个元素执行提供的操作。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>range(int startInclusive, int endExclusive)</td>
<td>返回有序的顺序IntStream从startInclusive（含）至 endExclusive通过增量步骤（独家） 1 。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>rangeClosed(int startInclusive, int endInclusive)</td>
<td>从 startInclusive （含）的顺序排列 IntStream到 endInclusive（含），增量步长为 1 。</td>
</tr>
<tr>
<td>OptionalInt</td>
<td>reduce(IntBinaryOperator op)</td>
<td>使用associative累积函数对此流的元素执行reduction ，并返回描述减小值的 OptionalInt （如果有）。</td>
</tr>
<tr>
<td>int</td>
<td>reduce(int identity, IntBinaryOperator op)</td>
<td>使用提供的身份值和associative累积功能对此流的元素执行reduction ，并返回减小的值。</td>
</tr>
<tr>
<td>IntStream</td>
<td>sequential()</td>
<td>返回顺序的等效流。</td>
</tr>
<tr>
<td>IntStream</td>
<td>skip(long n)</td>
<td>在丢弃流的第一个 n元素后，返回由该流的 n元素组成的流。</td>
</tr>
<tr>
<td>IntStream</td>
<td>sorted()</td>
<td>以排序顺序返回由该流的元素组成的流。</td>
</tr>
<tr>
<td>Spliterator.OfInt</td>
<td>spliterator()</td>
<td>返回此流的元素的拼接器。</td>
</tr>
<tr>
<td>int</td>
<td>sum()</td>
<td>返回此流中元素的总和。</td>
</tr>
<tr>
<td>IntSummaryStatistics</td>
<td>summaryStatistics()</td>
<td>返回一个 IntSummaryStatistics描述有关此流的元素的各种摘要数据。</td>
</tr>
<tr>
<td>int[]</td>
<td>toArray()</td>
<td>返回一个包含此流的元素的数组。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test5</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试allMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">allMatch</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).allMatch(<span class="keyword">new</span> <span class="title class_">IntPredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">int</span> age)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> age &lt; <span class="number">50</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否所有用户都小于50岁：&quot;</span> + allMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试anyMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">anyMatch</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).anyMatch(<span class="keyword">new</span> <span class="title class_">IntPredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">int</span> age)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> age &lt; <span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否存在年龄小于10岁的用户：&quot;</span> + anyMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试asDoubleStream()方法</span></span><br><span class="line">    <span class="type">DoubleStream</span> <span class="variable">doubleStream</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).asDoubleStream();</span><br><span class="line">    doubleStream.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试asLongStream()方法</span></span><br><span class="line">    <span class="type">LongStream</span> <span class="variable">longStream</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).asLongStream();</span><br><span class="line">    longStream.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试average()方法</span></span><br><span class="line">    <span class="type">OptionalDouble</span> <span class="variable">average</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).average();</span><br><span class="line">    System.out.println(<span class="string">&quot;用户评价年龄为：&quot;</span> + average.orElse(-<span class="number">1</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试boxed()方法</span></span><br><span class="line">    Stream&lt;Integer&gt; boxed = userList.stream().mapToInt(User::getAge).boxed();</span><br><span class="line">    System.out.println(<span class="string">&quot;通过装箱的Stream统计数量：&quot;</span> + boxed.count());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    <span class="type">IntStream</span> <span class="variable">build1</span> <span class="operator">=</span> IntStream.builder().add(<span class="number">1</span>).add(<span class="number">2</span>).add(<span class="number">3</span>).build();</span><br><span class="line">    System.out.println(<span class="string">&quot;遍历通过builder()方法创建的IntStream元素：&quot;</span>);</span><br><span class="line">    build1.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试collect()方法</span></span><br><span class="line">    Supplier&lt;List&lt;Integer&gt;&gt; supplier = <span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;List&lt;Integer&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> List&lt;Integer&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    ObjIntConsumer&lt;List&lt;Integer&gt;&gt; accumulator = <span class="keyword">new</span> <span class="title class_">ObjIntConsumer</span>&lt;List&lt;Integer&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;Integer&gt; list, <span class="type">int</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (value &gt; <span class="number">20</span>) &#123;</span><br><span class="line">                list.add(value);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    BiConsumer&lt;List&lt;Integer&gt;, List&lt;Integer&gt;&gt; combiner = <span class="keyword">new</span> <span class="title class_">BiConsumer</span>&lt;List&lt;Integer&gt;, List&lt;Integer&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;Integer&gt; list1, List&lt;Integer&gt; list2)</span> &#123;</span><br><span class="line">            list1.addAll(list2);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    List&lt;Integer&gt; collect = userList.stream()</span><br><span class="line">            .mapToInt(User::getAge)</span><br><span class="line">            .collect(supplier, accumulator, combiner);</span><br><span class="line">    System.out.println(<span class="string">&quot;列举所有大于20的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(collect);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试concat()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印两个连接起来的IntStream元素：&quot;</span>);</span><br><span class="line">    IntStream.concat(userList.stream().mapToInt(User::getAge), IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>)).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试count()方法</span></span><br><span class="line">    <span class="type">long</span> <span class="variable">count</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).count();</span><br><span class="line">    System.out.println(<span class="string">&quot;流中元素的总数：&quot;</span>);</span><br><span class="line">    System.out.println(count);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试distinct()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印去重后的年龄：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).distinct().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试empty()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;获取一个空的IntStream：&quot;</span>);</span><br><span class="line">    <span class="type">IntStream</span> <span class="variable">empty</span> <span class="operator">=</span> IntStream.empty();</span><br><span class="line">    System.out.println(empty);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试filter()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;过滤调年龄大于30的用户：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).filter(age -&gt; age &lt;= <span class="number">30</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findAny()方法，返回流中任意的一个元素并包装成OptionalInt，结果不稳定</span></span><br><span class="line">    <span class="type">int</span> <span class="variable">asInteger1</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).findAny().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中任意元素并包装成OptionalInt：&quot;</span>);</span><br><span class="line">    System.out.println(asInteger1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findFirst()方法，返回流中第一个元素并包装成OptionalInt，结果稳定</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">asInteger2</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).findFirst().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中首个元素并包装成OptionalInt：&quot;</span>);</span><br><span class="line">    System.out.println(asInteger2);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试flatMap()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;测试flatMap()方法，每人年龄+10岁：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).flatMap(<span class="keyword">new</span> <span class="title class_">IntFunction</span>&lt;IntStream&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> IntStream <span class="title function_">apply</span><span class="params">(<span class="type">int</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> IntStream.of(value + <span class="number">10</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEach()方法，不保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().mapToInt(User::getAge).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEachOrdered()方法，保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().mapToInt(User::getAge).forEachOrdered(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试generate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;随机生成10个数字：&quot;</span>);</span><br><span class="line">    <span class="type">Random</span> <span class="variable">random</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Random</span>();</span><br><span class="line">    <span class="type">int</span>[] ints = IntStream.generate(<span class="keyword">new</span> <span class="title class_">IntSupplier</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">getAsInt</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> random.nextInt();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(ints));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成10个等差数：&quot;</span>);</span><br><span class="line">    <span class="type">int</span>[] ints1 = IntStream.iterate(<span class="number">2</span>, <span class="keyword">new</span> <span class="title class_">IntUnaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(<span class="type">int</span> operand)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> operand + <span class="number">2</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(ints1));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    PrimitiveIterator.<span class="type">OfInt</span> <span class="variable">iterator</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).iterator();</span><br><span class="line">    System.out.println(<span class="string">&quot;通过iterate打印元素：&quot;</span>);</span><br><span class="line">    <span class="keyword">while</span> (iterator.hasNext()) &#123;</span><br><span class="line">        System.out.println(iterator.next());</span><br><span class="line">    &#125;</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试limit()方法</span></span><br><span class="line">    <span class="type">OptionalDouble</span> <span class="variable">average1</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).limit(<span class="number">3</span>).average();</span><br><span class="line">    System.out.println(<span class="string">&quot;求前三个用户的平均年龄：&quot;</span>);</span><br><span class="line">    System.out.println(average1.orElse(-<span class="number">1</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试map()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄+20岁：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).map(<span class="keyword">new</span> <span class="title class_">IntUnaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(<span class="type">int</span> operand)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> operand + <span class="number">20</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToInt()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为整型：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).mapToDouble(<span class="keyword">new</span> <span class="title class_">IntToDoubleFunction</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(<span class="type">int</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToLong()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为长整型：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).mapToLong(<span class="keyword">new</span> <span class="title class_">IntToLongFunction</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(<span class="type">int</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToObj()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为用户：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).mapToObj(<span class="keyword">new</span> <span class="title class_">IntFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(<span class="type">int</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> User.builder().age((<span class="type">int</span>) value).build();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试max()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">maxAge</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).max().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最大的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(maxAge);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试min()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">minAge</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).min().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最小的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(minAge);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试noneMatch()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回是否没有年龄大于100的用户：&quot;</span>);</span><br><span class="line">    <span class="type">boolean</span> <span class="variable">noneMatch</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).noneMatch(<span class="keyword">new</span> <span class="title class_">IntPredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">int</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value &gt; <span class="number">100</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(noneMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的多个元素序列：&quot;</span>);</span><br><span class="line">    IntStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的单个元素序列：&quot;</span>);</span><br><span class="line">    IntStream.of(<span class="number">1</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试parallel()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回并发流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.stream().mapToInt(User::getAge).parallel());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试peek()方法，是一个中间操作，主要用于调试</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印流中的每个元素：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).peek(<span class="keyword">new</span> <span class="title class_">IntConsumer</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(<span class="type">int</span> value)</span> &#123;</span><br><span class="line">            System.out.println(value);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).sum();</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试range()方法，不包含最后一个值</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成1~10的序列：&quot;</span>);</span><br><span class="line">    <span class="type">IntStream</span> <span class="variable">range</span> <span class="operator">=</span> IntStream.range(<span class="number">1</span>, <span class="number">11</span>);</span><br><span class="line">    range.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试rangeClosed()方法，包含最后一个值</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成1~10的序列：&quot;</span>);</span><br><span class="line">    <span class="type">IntStream</span> <span class="variable">rangeClosed</span> <span class="operator">=</span> IntStream.rangeClosed(<span class="number">1</span>, <span class="number">10</span>);</span><br><span class="line">    rangeClosed.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为流的第一个元素</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    <span class="type">int</span> <span class="variable">v</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).reduce(<span class="keyword">new</span> <span class="title class_">IntBinaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(<span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> left + right;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(v);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为identity（即第一个参数）</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    <span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).reduce(<span class="number">0</span>, <span class="keyword">new</span> <span class="title class_">IntBinaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(<span class="type">int</span> left, <span class="type">int</span> right)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> left + right;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(sum);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sequential()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回顺序流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.parallelStream().mapToInt(User::getAge).sequential());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试skip()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;跳过前三个元素：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).skip(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sorted()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;按年龄大小排序：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(User::getAge).sorted().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sum()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">sum1</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).sum();</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄总和：&quot;</span>);</span><br><span class="line">    System.out.println(sum1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summaryStatistics()方法，返回各种摘要信息</span></span><br><span class="line">    <span class="type">IntSummaryStatistics</span> <span class="variable">statistics</span> <span class="operator">=</span> userList.stream().mapToInt(User::getAge).summaryStatistics();</span><br><span class="line">    System.out.println(<span class="string">&quot;和：&quot;</span> + statistics.getSum());</span><br><span class="line">    System.out.println(<span class="string">&quot;数量：&quot;</span> + statistics.getCount());</span><br><span class="line">    System.out.println(<span class="string">&quot;最大值：&quot;</span> + statistics.getMax());</span><br><span class="line">    System.out.println(<span class="string">&quot;最小值：&quot;</span> + statistics.getMin());</span><br><span class="line">    System.out.println(<span class="string">&quot;平均值：&quot;</span> + statistics.getAverage());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toArray()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;转换为double数组：&quot;</span>);</span><br><span class="line">    <span class="type">int</span>[] doubles2 = userList.stream().mapToInt(User::getAge).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(doubles2));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br></pre></td><td class="code"><pre><span class="line">是否所有用户都小于50岁：true</span><br><span class="line">-----------------------</span><br><span class="line">是否存在年龄小于10岁的用户：false</span><br><span class="line">-----------------------</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">用户评价年龄为：24.0</span><br><span class="line">-----------------------</span><br><span class="line">通过装箱的Stream统计数量：5</span><br><span class="line">-----------------------</span><br><span class="line">遍历通过builder()方法创建的IntStream元素：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">-----------------------</span><br><span class="line">列举所有大于20的年龄：</span><br><span class="line">[28, 32, 21, 21]</span><br><span class="line">-----------------------</span><br><span class="line">打印两个连接起来的IntStream元素：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">-----------------------</span><br><span class="line">流中元素的总数：</span><br><span class="line">5</span><br><span class="line">-----------------------</span><br><span class="line">打印去重后的年龄：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">获取一个空的IntStream：</span><br><span class="line">java.util.stream.IntPipeline$Head@17a7cec2</span><br><span class="line">-----------------------</span><br><span class="line">过滤调年龄大于30的用户：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">返回流中任意元素并包装成OptionalInt：</span><br><span class="line">18</span><br><span class="line">-----------------------</span><br><span class="line">返回流中首个元素并包装成OptionalInt：</span><br><span class="line">18.0</span><br><span class="line">-----------------------</span><br><span class="line">测试flatMap()方法，每人年龄+10岁：</span><br><span class="line">28</span><br><span class="line">38</span><br><span class="line">42</span><br><span class="line">31</span><br><span class="line">31</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">28</span><br><span class="line">18</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">随机生成10个数字：</span><br><span class="line">[-225057879, 13099014, 1942130014, -1649359025, -831199561, 1727527066, -1937714752, -1356532121, -507030166, 457144123]</span><br><span class="line">-----------------------</span><br><span class="line">生成10个等差数：</span><br><span class="line">[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]</span><br><span class="line">通过iterate打印元素：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">求前三个用户的平均年龄：</span><br><span class="line">26.0</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄+20岁：</span><br><span class="line">38</span><br><span class="line">48</span><br><span class="line">52</span><br><span class="line">41</span><br><span class="line">41</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为整型：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为长整型：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为用户：</span><br><span class="line">User(age=18, height=null, weight=null, username=null)</span><br><span class="line">User(age=28, height=null, weight=null, username=null)</span><br><span class="line">User(age=32, height=null, weight=null, username=null)</span><br><span class="line">User(age=21, height=null, weight=null, username=null)</span><br><span class="line">User(age=21, height=null, weight=null, username=null)</span><br><span class="line">-----------------------</span><br><span class="line">获取最大的年龄：</span><br><span class="line">32.0</span><br><span class="line">-----------------------</span><br><span class="line">获取最小的年龄：</span><br><span class="line">18.0</span><br><span class="line">-----------------------</span><br><span class="line">返回是否没有年龄大于100的用户：</span><br><span class="line">true</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的多个元素序列：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的单个元素序列：</span><br><span class="line">1</span><br><span class="line">-----------------------</span><br><span class="line">返回并发流：</span><br><span class="line">java.util.stream.ReferencePipeline$4@506c589e</span><br><span class="line">-----------------------</span><br><span class="line">打印流中的每个元素：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">生成1~10的序列：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">-----------------------</span><br><span class="line">生成1~10的序列：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">120</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">120</span><br><span class="line">-----------------------</span><br><span class="line">返回顺序流：</span><br><span class="line">java.util.stream.ReferencePipeline$4@67424e82</span><br><span class="line">-----------------------</span><br><span class="line">跳过前三个元素：</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">按年龄大小排序：</span><br><span class="line">18</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">-----------------------</span><br><span class="line">求年龄总和：</span><br><span class="line">120.0</span><br><span class="line">-----------------------</span><br><span class="line">和：120</span><br><span class="line">数量：5</span><br><span class="line">最大值：32</span><br><span class="line">最小值：18</span><br><span class="line">平均值：24.0</span><br><span class="line">-----------------------</span><br><span class="line">转换为double数组：</span><br><span class="line">[18, 28, 32, 21, 21]</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<h3 id="IntStream-Builder"><a href="#IntStream-Builder" class="headerlink" title="IntStream.Builder"></a>IntStream.Builder</h3><p>IntStream.Builder是IntStream是构建器，IntStream.Builder具有生命周期，其从构建阶段开始，在该阶段期间可以添加元素，然后转换到内置阶段，之后可能不添加元素。构建阶段从调用build()方法开始，它创建一个有序流，其元素是添加到流构建器的元素，按照它们被添加的顺序。</p>
<p>IntStream.Builder提供以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>void</td>
<td>accept(int t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>default IntStream.Builder</td>
<td>add(int t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>IntStream</td>
<td>build()</td>
<td>构建流，将此构建器转换为内置状态。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test6</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    <span class="type">IntStream</span> <span class="variable">build1</span> <span class="operator">=</span> IntStream.builder().add(<span class="number">1</span>).add(<span class="number">2</span>).add(<span class="number">3</span>).build();</span><br><span class="line">    System.out.println(<span class="string">&quot;遍历通过builder()方法创建的IntStream元素：&quot;</span>);</span><br><span class="line">    build1.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">遍历通过builder()方法创建的IntStream元素：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<p>IntStream.Builderd的accept(double t)方法只在IntStreamBuilderImpl中有实现，IntStreamBuilderImpl在两个地方有用法：</p>
<ol>
<li>IntStream的builder()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回IntStreamBuilderImpl实例</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> Builder <span class="title function_">builder</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Streams</span>.IntStreamBuilderImpl();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>IntStream的of()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回具有单个元素的IntStream </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> IntStream <span class="title function_">of</span><span class="params">(<span class="type">int</span> t)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> StreamSupport.intStream(<span class="keyword">new</span> <span class="title class_">Streams</span>.IntStreamBuilderImpl(t), <span class="literal">false</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="LongStream"><a href="#LongStream" class="headerlink" title="LongStream"></a>LongStream</h3><p>LongStream支持顺序和并行聚合操作的原始long值元素序列，是long原始专长Stream。</p>
<p>LongStream有以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>boolean</td>
<td>allMatch(LongPredicate predicate)</td>
<td>返回此流的所有元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>boolean</td>
<td>anyMatch(LongPredicate predicate)</td>
<td>返回此流的任何元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>asDoubleStream()</td>
<td>返回一个 DoubleStream由该流中的元素，转换为 double 。</td>
</tr>
<tr>
<td>OptionalDouble</td>
<td>average()</td>
<td>返回 OptionalDouble此流的元素的算术平均值的OptionalDouble，如果此流为空，则返回一个空的可选项。</td>
</tr>
<tr>
<td>Stream<Long></td>
<td>boxed()</td>
<td>返回一个 Stream由该流的盒装到所述的元件，每个的 Long 。</td>
</tr>
<tr>
<td>static LongStream.Builder</td>
<td>builder()</td>
<td>返回一个 LongStream的生成器。</td>
</tr>
<tr>
<td><R> R</td>
<td>collect(Supplier<R> supplier, ObjLongConsumer<R> accumulator, BiConsumer&lt;R,R&gt; combiner)</td>
<td>对此流的元素执行mutable reduction操作。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>concat(LongStream a, LongStream b)</td>
<td>创建一个懒惰连接的流，其元素是第一个流的所有元素，后跟第二个流的所有元素。</td>
</tr>
<tr>
<td>long</td>
<td>count()</td>
<td>返回此流中的元素数。</td>
</tr>
<tr>
<td>LongStream</td>
<td>distinct()</td>
<td>返回由该流的不同元素组成的流。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>empty()</td>
<td>返回一个空的顺序 LongStream 。</td>
</tr>
<tr>
<td>LongStream</td>
<td>filter(LongPredicate predicate)</td>
<td>返回由与此给定谓词匹配的此流的元素组成的流。</td>
</tr>
<tr>
<td>OptionalLong</td>
<td>findAny()</td>
<td>返回描述流的一些元素的OptionalLong如果流为空，则返回一个空的OptionalLong 。</td>
</tr>
<tr>
<td>OptionalLong</td>
<td>findFirst()</td>
<td>返回描述此流的第一个元素的OptionalLong如果流为空，则返回空的OptionalLong 。</td>
</tr>
<tr>
<td>LongStream</td>
<td>flatMap(LongFunction&lt;? extends LongStream&gt; mapper)</td>
<td>返回由通过将提供的映射函数应用于每个元素而产生的映射流的内容来替换该流的每个元素的结果的流。</td>
</tr>
<tr>
<td>void</td>
<td>forEach(LongConsumer action)</td>
<td>对此流的每个元素执行操作。</td>
</tr>
<tr>
<td>void</td>
<td>forEachOrdered(LongConsumer action)</td>
<td>对此流的每个元素执行一个操作，保证每个元素按遇到顺序处理，以便具有定义的遇到顺序的流。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>generate(LongSupplier s)</td>
<td>返回无限顺序无序流，其中每个元素由提供的 LongSupplier 。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>iterate(long seed, LongUnaryOperator f)</td>
<td>返回有序无限连续 LongStream由函数的迭代应用产生 f至初始元素 seed ，产生 Stream包括 seed ， f(seed) ， f(f(seed)) ，等</td>
</tr>
<tr>
<td>PrimitiveIterator.OfLong</td>
<td>iterator()</td>
<td>返回此流的元素的迭代器。</td>
</tr>
<tr>
<td>LongStream</td>
<td>limit(long maxSize)</td>
<td>返回由此流的元素组成的流，截断长度不能超过 maxSize 。</td>
</tr>
<tr>
<td>LongStream</td>
<td>map(LongUnaryOperator mapper)</td>
<td>返回由给定函数应用于此流的元素的结果组成的流。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>mapToDouble(LongToDoubleFunction mapper)</td>
<td>返回一个 DoubleStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>IntStream</td>
<td>mapToInt(LongToIntFunction mapper)</td>
<td>返回一个 IntStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td><U> Stream<U></td>
<td>mapToObj(LongFunction&lt;? extends U&gt; mapper)</td>
<td>返回一个对象值 Stream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>OptionalLong</td>
<td>max()</td>
<td>返回 OptionalLong此流的最大元素的OptionalLong，如果此流为空，则返回一个空的可选项。</td>
</tr>
<tr>
<td>OptionalLong</td>
<td>min()</td>
<td>返回 OptionalLong此流的最小元素的OptionalLong，如果此流为空，则返回一个空的可选项。</td>
</tr>
<tr>
<td>boolean</td>
<td>noneMatch(LongPredicate predicate)</td>
<td>返回此流的元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>of(long… values)</td>
<td>返回其元素是指定值的顺序排序流。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>of(long t)</td>
<td>返回包含单个元素的顺序 LongStream 。</td>
</tr>
<tr>
<td>LongStream</td>
<td>parallel()</td>
<td>返回平行的等效流。</td>
</tr>
<tr>
<td>LongStream</td>
<td>peek(LongConsumer action)</td>
<td>返回由该流的元素组成的流，另外在从生成的流中消耗元素时对每个元素执行提供的操作。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>range(long startInclusive, long endExclusive) 。</td>
<td>返回有序的顺序 LongStream从 startInclusive （含）至 endExclusive通过增量步骤（独家） 1</td>
</tr>
<tr>
<td>static LongStream</td>
<td>rangeClosed(long startInclusive, long endInclusive)</td>
<td>返回有序顺序 LongStream从 startInclusive （含）至 endInclusive通过的递增步长（含） 1 。</td>
</tr>
<tr>
<td>OptionalLong</td>
<td>reduce(LongBinaryOperator op)</td>
<td>使用 associative累积功能对此流的元素执行reduction ，并返回描述减小值的 OptionalLong （如果有）。</td>
</tr>
<tr>
<td>long</td>
<td>reduce(long identity, LongBinaryOperator op)</td>
<td>使用提供的身份值和associative累积功能对此流的元素执行reduction ，并返回减小的值。</td>
</tr>
<tr>
<td>LongStream</td>
<td>sequential()</td>
<td>返回顺序的等效流。</td>
</tr>
<tr>
<td>LongStream</td>
<td>skip(long n)</td>
<td>在丢弃流的第一个 n元素后，返回由该流的 n元素组成的流。</td>
</tr>
<tr>
<td>LongStream</td>
<td>sorted()</td>
<td>以排序顺序返回由该流的元素组成的流。</td>
</tr>
<tr>
<td>Spliterator.OfLong</td>
<td>spliterator()</td>
<td>返回此流的元素的拼接器。</td>
</tr>
<tr>
<td>long</td>
<td>sum()</td>
<td>返回此流中元素的总和。</td>
</tr>
<tr>
<td>LongSummaryStatistics</td>
<td>summaryStatistics()</td>
<td>返回一个 LongSummaryStatistics描述有关此流的元素的各种摘要数据。</td>
</tr>
<tr>
<td>long[]</td>
<td>toArray()</td>
<td>返回一个包含此流的元素的数组。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test7</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试allMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">allMatch</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).allMatch(<span class="keyword">new</span> <span class="title class_">LongPredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">long</span> age)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> age &lt; <span class="number">50</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否所有用户都小于50岁：&quot;</span> + allMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试anyMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">anyMatch</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).anyMatch(<span class="keyword">new</span> <span class="title class_">LongPredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">long</span> age)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> age &lt; <span class="number">10</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否存在年龄小于10岁的用户：&quot;</span> + anyMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试asDoubleStream()方法</span></span><br><span class="line">    <span class="type">DoubleStream</span> <span class="variable">doubleStream</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).asDoubleStream();</span><br><span class="line">    doubleStream.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试average()方法</span></span><br><span class="line">    <span class="type">OptionalDouble</span> <span class="variable">average</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).average();</span><br><span class="line">    System.out.println(<span class="string">&quot;用户评价年龄为：&quot;</span> + average.orElse(-<span class="number">1</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试boxed()方法</span></span><br><span class="line">    Stream&lt;Long&gt; boxed = userList.stream().mapToLong(User::getAge).boxed();</span><br><span class="line">    System.out.println(<span class="string">&quot;通过装箱的Stream统计数量：&quot;</span> + boxed.count());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    <span class="type">LongStream</span> <span class="variable">build1</span> <span class="operator">=</span> LongStream.builder().add(<span class="number">1</span>).add(<span class="number">2</span>).add(<span class="number">3</span>).build();</span><br><span class="line">    System.out.println(<span class="string">&quot;遍历通过builder()方法创建的LongStream元素：&quot;</span>);</span><br><span class="line">    build1.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试collect()方法</span></span><br><span class="line">    Supplier&lt;List&lt;Long&gt;&gt; supplier = <span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;List&lt;Long&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> List&lt;Long&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    ObjLongConsumer&lt;List&lt;Long&gt;&gt; accumulator = <span class="keyword">new</span> <span class="title class_">ObjLongConsumer</span>&lt;List&lt;Long&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;Long&gt; list, <span class="type">long</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (value &gt; <span class="number">20</span>) &#123;</span><br><span class="line">                list.add(value);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    BiConsumer&lt;List&lt;Long&gt;, List&lt;Long&gt;&gt; combiner = <span class="keyword">new</span> <span class="title class_">BiConsumer</span>&lt;List&lt;Long&gt;, List&lt;Long&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(List&lt;Long&gt; list1, List&lt;Long&gt; list2)</span> &#123;</span><br><span class="line">            list1.addAll(list2);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;;</span><br><span class="line">    List&lt;Long&gt; collect = userList.stream()</span><br><span class="line">            .mapToLong(User::getAge)</span><br><span class="line">            .collect(supplier, accumulator, combiner);</span><br><span class="line">    System.out.println(<span class="string">&quot;列举所有大于20的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(collect);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试concat()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印两个连接起来的LongStream元素：&quot;</span>);</span><br><span class="line">    LongStream.concat(userList.stream().mapToLong(User::getAge), LongStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>)).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试count()方法</span></span><br><span class="line">    <span class="type">long</span> <span class="variable">count</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).count();</span><br><span class="line">    System.out.println(<span class="string">&quot;流中元素的总数：&quot;</span>);</span><br><span class="line">    System.out.println(count);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试distinct()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印去重后的年龄：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).distinct().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试empty()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;获取一个空的LongStream：&quot;</span>);</span><br><span class="line">    <span class="type">LongStream</span> <span class="variable">empty</span> <span class="operator">=</span> LongStream.empty();</span><br><span class="line">    System.out.println(empty);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试filter()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;过滤调年龄大于30的用户：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).filter(age -&gt; age &lt;= <span class="number">30</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findAny()方法，返回流中任意的一个元素并包装成OptionalLong，结果不稳定</span></span><br><span class="line">    <span class="type">long</span> <span class="variable">asInteger1</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).findAny().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中任意元素并包装成OptionalLong：&quot;</span>);</span><br><span class="line">    System.out.println(asInteger1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findFirst()方法，返回流中第一个元素并包装成OptionalInt，结果稳定</span></span><br><span class="line">    <span class="type">long</span> <span class="variable">asInteger2</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).findFirst().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中首个元素并包装成OptionalLong：&quot;</span>);</span><br><span class="line">    System.out.println(asInteger2);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试flatMap()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;测试flatMap()方法，每人年龄+10岁：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).flatMap(<span class="keyword">new</span> <span class="title class_">LongFunction</span>&lt;LongStream&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> LongStream <span class="title function_">apply</span><span class="params">(<span class="type">long</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> LongStream.of(value + <span class="number">10</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEach()方法，不保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().mapToLong(User::getAge).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEachOrdered()方法，保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().mapToLong(User::getAge).forEachOrdered(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试generate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;随机生成10个数字：&quot;</span>);</span><br><span class="line">    <span class="type">Random</span> <span class="variable">random</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Random</span>();</span><br><span class="line">    <span class="type">long</span>[] longs = LongStream.generate(<span class="keyword">new</span> <span class="title class_">LongSupplier</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">getAsLong</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> random.nextInt();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(longs));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成10个等差数：&quot;</span>);</span><br><span class="line">    <span class="type">long</span>[] longs1 = LongStream.iterate(<span class="number">2</span>, <span class="keyword">new</span> <span class="title class_">LongUnaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(<span class="type">long</span> operand)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> operand + <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(longs1));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    PrimitiveIterator.<span class="type">OfLong</span> <span class="variable">iterator</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).iterator();</span><br><span class="line">    System.out.println(<span class="string">&quot;通过iterate打印元素：&quot;</span>);</span><br><span class="line">    <span class="keyword">while</span> (iterator.hasNext()) &#123;</span><br><span class="line">        System.out.println(iterator.next());</span><br><span class="line">    &#125;</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试limit()方法</span></span><br><span class="line">    <span class="type">OptionalDouble</span> <span class="variable">average1</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).limit(<span class="number">3</span>).average();</span><br><span class="line">    System.out.println(<span class="string">&quot;求前三个用户的平均年龄：&quot;</span>);</span><br><span class="line">    System.out.println(average1.orElse(-<span class="number">1</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试map()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄+20岁：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).map(<span class="keyword">new</span> <span class="title class_">LongUnaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(<span class="type">long</span> operand)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> operand + <span class="number">20</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToInt()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为整型：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).mapToInt(<span class="keyword">new</span> <span class="title class_">LongToIntFunction</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(<span class="type">long</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> (<span class="type">int</span>)value;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToDouble()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为浮点型：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).mapToDouble(<span class="keyword">new</span> <span class="title class_">LongToDoubleFunction</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(<span class="type">long</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToObj()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄映射为用户：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).mapToObj(<span class="keyword">new</span> <span class="title class_">LongFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(<span class="type">long</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> User.builder().age((<span class="type">int</span>) value).build();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试max()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">maxAge</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).max().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最大的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(maxAge);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试min()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">minAge</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).min().orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最小的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(minAge);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试noneMatch()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回是否没有年龄大于100的用户：&quot;</span>);</span><br><span class="line">    <span class="type">boolean</span> <span class="variable">noneMatch</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).noneMatch(<span class="keyword">new</span> <span class="title class_">LongPredicate</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(<span class="type">long</span> value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value &gt; <span class="number">100</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(noneMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的多个元素序列：&quot;</span>);</span><br><span class="line">    LongStream.of(<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的单个元素序列：&quot;</span>);</span><br><span class="line">    LongStream.of(<span class="number">1</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试parallel()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回并发流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.stream().mapToLong(User::getAge).parallel());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试peek()方法，是一个中间操作，主要用于调试</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印流中的每个元素：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).peek(<span class="keyword">new</span> <span class="title class_">LongConsumer</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(<span class="type">long</span> value)</span> &#123;</span><br><span class="line">            System.out.println(value);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).sum();</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试range()方法，不包含最后一个值</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成1~10的序列：&quot;</span>);</span><br><span class="line">    <span class="type">LongStream</span> <span class="variable">range</span> <span class="operator">=</span> LongStream.range(<span class="number">1</span>, <span class="number">11</span>);</span><br><span class="line">    range.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试rangeClosed()方法，包含最后一个值</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成1~10的序列：&quot;</span>);</span><br><span class="line">    <span class="type">LongStream</span> <span class="variable">rangeClosed</span> <span class="operator">=</span> LongStream.rangeClosed(<span class="number">1</span>, <span class="number">10</span>);</span><br><span class="line">    rangeClosed.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为流的第一个元素</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    <span class="type">long</span> <span class="variable">v</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).reduce(<span class="keyword">new</span> <span class="title class_">LongBinaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(<span class="type">long</span> left, <span class="type">long</span> right)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> left + right;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).orElse(-<span class="number">1</span>);</span><br><span class="line">    System.out.println(v);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为identity（即第一个参数）</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    <span class="type">long</span> <span class="variable">sum</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).reduce(<span class="number">0</span>, <span class="keyword">new</span> <span class="title class_">LongBinaryOperator</span>() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(<span class="type">long</span> left, <span class="type">long</span> right)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> left + right;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(sum);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sequential()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回顺序流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.parallelStream().mapToLong(User::getAge).sequential());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试skip()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;跳过前三个元素：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).skip(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sorted()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;按年龄大小排序：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(User::getAge).sorted().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sum()方法</span></span><br><span class="line">    <span class="type">double</span> <span class="variable">sum1</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).sum();</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄总和：&quot;</span>);</span><br><span class="line">    System.out.println(sum1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summaryStatistics()方法，返回各种摘要信息</span></span><br><span class="line">    <span class="type">LongSummaryStatistics</span> <span class="variable">statistics</span> <span class="operator">=</span> userList.stream().mapToLong(User::getAge).summaryStatistics();</span><br><span class="line">    System.out.println(<span class="string">&quot;和：&quot;</span> + statistics.getSum());</span><br><span class="line">    System.out.println(<span class="string">&quot;数量：&quot;</span> + statistics.getCount());</span><br><span class="line">    System.out.println(<span class="string">&quot;最大值：&quot;</span> + statistics.getMax());</span><br><span class="line">    System.out.println(<span class="string">&quot;最小值：&quot;</span> + statistics.getMin());</span><br><span class="line">    System.out.println(<span class="string">&quot;平均值：&quot;</span> + statistics.getAverage());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toArray()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;转换为long数组：&quot;</span>);</span><br><span class="line">    <span class="type">long</span>[] longs2 = userList.stream().mapToLong(User::getAge).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(longs2));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br></pre></td><td class="code"><pre><span class="line">是否所有用户都小于50岁：true</span><br><span class="line">-----------------------</span><br><span class="line">是否存在年龄小于10岁的用户：false</span><br><span class="line">-----------------------</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">用户评价年龄为：24.0</span><br><span class="line">-----------------------</span><br><span class="line">通过装箱的Stream统计数量：5</span><br><span class="line">-----------------------</span><br><span class="line">遍历通过builder()方法创建的LongStream元素：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">-----------------------</span><br><span class="line">列举所有大于20的年龄：</span><br><span class="line">[28, 32, 21, 21]</span><br><span class="line">-----------------------</span><br><span class="line">打印两个连接起来的LongStream元素：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">-----------------------</span><br><span class="line">流中元素的总数：</span><br><span class="line">5</span><br><span class="line">-----------------------</span><br><span class="line">打印去重后的年龄：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">获取一个空的LongStream：</span><br><span class="line">java.util.stream.LongPipeline$Head@70177ecd</span><br><span class="line">-----------------------</span><br><span class="line">过滤调年龄大于30的用户：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">返回流中任意元素并包装成OptionalLong：</span><br><span class="line">18</span><br><span class="line">-----------------------</span><br><span class="line">返回流中首个元素并包装成OptionalLong：</span><br><span class="line">18</span><br><span class="line">-----------------------</span><br><span class="line">测试flatMap()方法，每人年龄+10岁：</span><br><span class="line">28</span><br><span class="line">38</span><br><span class="line">42</span><br><span class="line">31</span><br><span class="line">31</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">28</span><br><span class="line">18</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">随机生成10个数字：</span><br><span class="line">[544954945, -857768077, -207128286, 69120021, 793453961, -7796011, 549982729, 1902220118, 1969892020, 354573389]</span><br><span class="line">-----------------------</span><br><span class="line">生成10个等差数：</span><br><span class="line">[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]</span><br><span class="line">通过iterate打印元素：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">求前三个用户的平均年龄：</span><br><span class="line">26.0</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄+20岁：</span><br><span class="line">38</span><br><span class="line">48</span><br><span class="line">52</span><br><span class="line">41</span><br><span class="line">41</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为整型：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为浮点型：</span><br><span class="line">18.0</span><br><span class="line">28.0</span><br><span class="line">32.0</span><br><span class="line">21.0</span><br><span class="line">21.0</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄映射为用户：</span><br><span class="line">User(age=18, height=null, weight=null, username=null)</span><br><span class="line">User(age=28, height=null, weight=null, username=null)</span><br><span class="line">User(age=32, height=null, weight=null, username=null)</span><br><span class="line">User(age=21, height=null, weight=null, username=null)</span><br><span class="line">User(age=21, height=null, weight=null, username=null)</span><br><span class="line">-----------------------</span><br><span class="line">获取最大的年龄：</span><br><span class="line">32.0</span><br><span class="line">-----------------------</span><br><span class="line">获取最小的年龄：</span><br><span class="line">18.0</span><br><span class="line">-----------------------</span><br><span class="line">返回是否没有年龄大于100的用户：</span><br><span class="line">true</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的多个元素序列：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的单个元素序列：</span><br><span class="line">1</span><br><span class="line">-----------------------</span><br><span class="line">返回并发流：</span><br><span class="line">java.util.stream.ReferencePipeline$5@5ce65a89</span><br><span class="line">-----------------------</span><br><span class="line">打印流中的每个元素：</span><br><span class="line">18</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">生成1~10的序列：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">-----------------------</span><br><span class="line">生成1~10的序列：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">120</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">120</span><br><span class="line">-----------------------</span><br><span class="line">返回顺序流：</span><br><span class="line">java.util.stream.ReferencePipeline$5@799f7e29</span><br><span class="line">-----------------------</span><br><span class="line">跳过前三个元素：</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">-----------------------</span><br><span class="line">按年龄大小排序：</span><br><span class="line">18</span><br><span class="line">21</span><br><span class="line">21</span><br><span class="line">28</span><br><span class="line">32</span><br><span class="line">-----------------------</span><br><span class="line">求年龄总和：</span><br><span class="line">120.0</span><br><span class="line">-----------------------</span><br><span class="line">和：120</span><br><span class="line">数量：5</span><br><span class="line">最大值：32</span><br><span class="line">最小值：18</span><br><span class="line">平均值：24.0</span><br><span class="line">-----------------------</span><br><span class="line">转换为long数组：</span><br><span class="line">[18, 28, 32, 21, 21]</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<h3 id="LongStream-Builder"><a href="#LongStream-Builder" class="headerlink" title="LongStream.Builder"></a>LongStream.Builder</h3><p>LongStream.Builder是LongStream是构建器，LongStream.Builder具有生命周期，其从构建阶段开始，在该阶段期间可以添加元素，然后转换到内置阶段，之后可能不添加元素。构建阶段从调用build()方法开始，它创建一个有序流，其元素是添加到流构建器的元素，按照它们被添加的顺序。</p>
<p>LongStream.Builder提供以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>void</td>
<td>accept(long t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>default LongStream.Builder</td>
<td>add(long t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>LongStream</td>
<td>build()</td>
<td>构建流，将此构建器转换为内置状态。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test8</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    <span class="type">LongStream</span> <span class="variable">build1</span> <span class="operator">=</span> LongStream.builder().add(<span class="number">1</span>).add(<span class="number">2</span>).add(<span class="number">3</span>).build();</span><br><span class="line">    System.out.println(<span class="string">&quot;遍历通过builder()方法创建的LongStream元素：&quot;</span>);</span><br><span class="line">    build1.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">遍历通过builder()方法创建的LongStream元素：</span><br><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<p>LongStream.Builderd的accept(double t)方法只在LongStreamBuilderImpl中有实现，LongStreamBuilderImpl在两个地方有用法：</p>
<ol>
<li>LongStream的builder()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回LongStreamBuilderImpl实例</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> Builder <span class="title function_">builder</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Streams</span>.LongStreamBuilderImpl();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>LongStream的of()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回具有单个元素的LongStream </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> LongStream <span class="title function_">of</span><span class="params">(<span class="type">long</span> t)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> StreamSupport.longStream(<span class="keyword">new</span> <span class="title class_">Streams</span>.LongStreamBuilderImpl(t), <span class="literal">false</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="Stream"><a href="#Stream" class="headerlink" title="Stream"></a>Stream</h3><p>支持顺序和并行聚合操作的一系列元素。以下示例说明了使用Stream和IntStream的汇总操作：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">sum</span> <span class="operator">=</span> widgets.stream().filter(w -&gt; w.getColor() == RED).mapToInt(w -&gt; w.getWeight()).sum();  </span><br></pre></td></tr></table></figure>

<p>在这个例子中，widgets是Collection<Widget>。我们通过Collection.stream()创建一个Widget对象的流，过滤它以产生仅包含红色小部件的流，然后将其转换为表示每个红色小部件的权重的int值。然后将该流相加以产生总重量。</p>
<p>除了Stream为对象引用的流，还存在IntStream、LongStream和DoubleStream。</p>
<p>为了执行计算，流operations被组合成<strong>pipelines</strong>。  pipelines由源（其可以是数组、集合、生成函数、I&#x2F;O通道等）组成，零个或多个<strong>中间操作</strong>（其将流转换成另一个流，例如filter(Predicate)）以及<strong>终端操作</strong>（产生结果或副作用，如count()或forEach(Consumer)）。流具有<strong>懒惰性</strong>，源数据上的计算仅在终端操作启动时执行，源元素仅在需要时才被使用。</p>
<p>集合和流，具有一些表面上的相似之处，但具有不同的目标。集合主要关注其元素的有效管理和访问。相比之下，流不提供直接访问或操纵其元素的手段，而是关心描述其源和将在该源上进行聚合的计算操作。但是，如果提供的流操作不提供所需的功能，则可以使用BaseStream.iterator()和BaseStream.spliterator()操作来执行受控遍历。</p>
<p><strong>pipelines</strong>，如上面的“小部件”示例，可以被视为流源上的<strong>查询</strong> 。除非源是明确设计用于并发修改（例如ConcurrentHashMap），否则在查询流源时可能会导致不可预测或错误的行为。</p>
<p>大多数流操作接受用户指定行为的参数，例如上面示例中传递给mapToInt的lambda表达式w-&gt;w.getWeight() 。为了保持正确的行为，这些<strong>行为参数</strong> ：</p>
<ul>
<li>必须是non-interfering（他们不修改流源）。</li>
<li>在大多数情况下必须是stateless（它们的结果不应该取决于在pipelines的执行期间可能改变的任何状态）。</li>
</ul>
<p>这些参数始终是functional interface的实例，例如Function，并且通常是lambda表达式或方法引用。除非另有说明，否则这些参数必须<strong>为非空值</strong> 。</p>
<p>一个流应该只操作一次（调用中间或终端流操作）。例如，这排除了“分叉”流，即同一个源提供两个或多个管道，或同一流的多次遍历。如果流实现检测到流正在被重用，它可能会抛出IllegalStateException。然而，由于一些流操作可能返回它们的接收器而不是新的流对象，因此不可能在所有情况下都检测到重用。</p>
<p>Streams有一个BaseStream.close()方法并实现了AutoCloseable，但几乎所有的流实例在使用后都不需要关闭。通常，只有源为IO通道的流（例如由Files.lines（Path，Charset）返回的流）才需要关闭。大多数流都由集合、数组或生成函数支持，这些函数不需要特殊的资源管理。（如果流确实需要关闭，则可以在try-with-resources语句中将其声明为资源。）</p>
<p>流管道可以按顺序执行，也可以并行执行。此执行模式是流的一个属性。流是通过顺序执行或并行执行的初始选择创建的。（例如，Collection.stream()创建一个顺序流，Collection.sparallelStream()创建并行流。）这种执行模式的选择可以通过BaseStream.sequential()或BaseStream.parallel()方法进行修改，也可以使用BaseStream.isParallel()判断是否为并行流。</p>
<p>Stream有以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>boolean</td>
<td>allMatch(Predicate&lt;? super T&gt; predicate)</td>
<td>返回此流的所有元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>boolean</td>
<td>anyMatch(Predicate&lt;? super T&gt; predicate)</td>
<td>返回此流的任何元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>static <T> Stream.Builder<T></td>
<td>builder()</td>
<td>返回一个Stream的构建器。</td>
</tr>
<tr>
<td>&lt;R,A&gt; R</td>
<td>collect(Collector&lt;? super T,A,R&gt; collector)</td>
<td>使用Collector对此流的元素执行mutable reduction Collector 。</td>
</tr>
<tr>
<td><R> R</td>
<td>collect(Supplier<R> supplier, BiConsumer&lt;R,? super T&gt; accumulator, BiConsumer&lt;R,R&gt; combiner)</td>
<td>对此流的元素执行mutable reduction操作。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>concat(Stream&lt;? extends T&gt; a, Stream&lt;? extends T&gt; b)</td>
<td>创建一个懒惰连接的流，其元素是第一个流的所有元素，后跟第二个流的所有元素。</td>
</tr>
<tr>
<td>long</td>
<td>count()</td>
<td>返回此流中的元素数。</td>
</tr>
<tr>
<td>Stream<T></td>
<td>distinct()</td>
<td>返回由该流的不同元素（根据 Object.equals(Object) ）组成的流。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>empty()</td>
<td>返回一个空的顺序Stream 。</td>
</tr>
<tr>
<td>Stream<T></td>
<td>filter(Predicate&lt;? super T&gt; predicate)</td>
<td>返回由与此给定谓词匹配的此流的元素组成的流。</td>
</tr>
<tr>
<td>Optional<T></td>
<td>findAny()</td>
<td>返回描述流的一些元素的Optional如果流为空，则返回一个空的Optional 。</td>
</tr>
<tr>
<td>Optional<T></td>
<td>findFirst()</td>
<td>返回描述此流的第一个元素的Optional如果流为空，则返回一个空的Optional 。</td>
</tr>
<tr>
<td><R> Stream<R></td>
<td>flatMap(Function&lt;? super T,? extends Stream&lt;? extends R&gt;&gt; mapper)</td>
<td>返回由通过将提供的映射函数应用于每个元素而产生的映射流的内容来替换该流的每个元素的结果的流。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>flatMapToDouble(Function&lt;? super T,? extends DoubleStream&gt; mapper)</td>
<td>返回一个DoubleStream ，其中包含将该流的每个元素替换为通过将提供的映射函数应用于每个元素而产生的映射流的内容的结果。</td>
</tr>
<tr>
<td>IntStream</td>
<td>flatMapToInt(Function&lt;? super T,? extends IntStream&gt; mapper)</td>
<td>返回一个 IntStream ，其中包含将该流的每个元素替换为通过将提供的映射函数应用于每个元素而产生的映射流的内容的结果。</td>
</tr>
<tr>
<td>LongStream</td>
<td>flatMapToLong(Function&lt;? super T,? extends LongStream&gt; mapper)</td>
<td>返回一个 LongStream ，其中包含将该流的每个元素替换为通过将提供的映射函数应用于每个元素而产生的映射流的内容的结果。</td>
</tr>
<tr>
<td>void</td>
<td>forEach(Consumer&lt;? super T&gt; action)</td>
<td>对此流的每个元素执行操作。</td>
</tr>
<tr>
<td>void</td>
<td>forEachOrdered(Consumer&lt;? super T&gt; action)</td>
<td>如果流具有定义的遇到顺序，则以流的遇到顺序对该流的每个元素执行操作。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>generate(Supplier<T> s)</td>
<td>返回无限顺序无序流，其中每个元素由提供的 Supplier 。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>iterate(T seed, UnaryOperator<T> f)</td>
<td>返回有序无限连续 Stream由函数的迭代应用产生 f至初始元素 seed ，产生 Stream包括seed，f(seed) ，f(f(seed)) ，等</td>
</tr>
<tr>
<td>Stream<T></td>
<td>limit(long maxSize)</td>
<td>返回由此流的元素组成的流，截短长度不能超过maxSize 。</td>
</tr>
<tr>
<td><R> Stream<R></td>
<td>map(Function&lt;? super T,? extends R&gt; mapper)</td>
<td>返回由给定函数应用于此流的元素的结果组成的流。</td>
</tr>
<tr>
<td>DoubleStream</td>
<td>mapToDouble(ToDoubleFunction&lt;? super T&gt; mapper)</td>
<td>返回一个DoubleStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>IntStream</td>
<td>mapToInt(ToIntFunction&lt;? super T&gt; mapper)</td>
<td>返回一个IntStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>LongStream</td>
<td>mapToLong(ToLongFunction&lt;? super T&gt; mapper)</td>
<td>返回一个LongStream ，其中包含将给定函数应用于此流的元素的结果。</td>
</tr>
<tr>
<td>Optional<T></td>
<td>max(Comparator&lt;? super T&gt; comparator)</td>
<td>根据提供的 Comparator返回此流的最大元素。</td>
</tr>
<tr>
<td>Optional<T></td>
<td>min(Comparator&lt;? super T&gt; comparator)</td>
<td>根据提供的 Comparator返回此流的最小元素。</td>
</tr>
<tr>
<td>boolean</td>
<td>noneMatch(Predicate&lt;? super T&gt; predicate)</td>
<td>返回此流的元素是否与提供的谓词匹配。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>of(T… values)</td>
<td>返回其元素是指定值的顺序排序流。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>of(T t)</td>
<td>返回包含单个元素的顺序Stream 。</td>
</tr>
<tr>
<td>Stream<T></td>
<td>peek(Consumer&lt;? super T&gt; action)</td>
<td>返回由该流的元素组成的流，另外在从生成的流中消耗元素时对每个元素执行提供的操作。</td>
</tr>
<tr>
<td>Optional<T></td>
<td>reduce(BinaryOperator<T> accumulator)</td>
<td>使用associative累积函数对此流的元素执行reduction，并返回描述减小值的Optional（如果有）。</td>
</tr>
<tr>
<td>T</td>
<td>reduce(T identity, BinaryOperator<T> accumulator)</td>
<td>使用提供的身份值和associative累积功能对此流的元素执行 reduction，并返回减小的值。</td>
</tr>
<tr>
<td><U> U</td>
<td>reduce(U identity, BiFunction&lt;U,? super T,U&gt; accumulator, BinaryOperator<U> combiner)</td>
<td>执行reduction在此流中的元素，使用所提供的身份，积累和组合功能。</td>
</tr>
<tr>
<td>Stream<T></td>
<td>skip(long n)</td>
<td>在丢弃流的第一个n元素后，返回由该流的n元素组成的流。</td>
</tr>
<tr>
<td>Stream<T></td>
<td>sorted()</td>
<td>返回由此流的元素组成的流，根据自然顺序排序。</td>
</tr>
<tr>
<td>Stream<T></td>
<td>sorted(Comparator&lt;? super T&gt; comparator)</td>
<td>返回由该流的元素组成的流，根据提供的Comparator进行排序。</td>
</tr>
<tr>
<td>Object[]</td>
<td>toArray()</td>
<td>返回一个包含此流的元素的数组。</td>
</tr>
<tr>
<td><A> A[]</td>
<td>toArray(IntFunction&lt;A[]&gt; generator)</td>
<td>使用提供的generator函数返回一个包含此流的元素的数组，以分配返回的数组，以及分区执行或调整大小可能需要的任何其他数组。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test9</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试allMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">allMatch</span> <span class="operator">=</span> userList.stream().allMatch(<span class="keyword">new</span> <span class="title class_">Predicate</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> user.getAge() &lt; <span class="number">35</span> &amp;&amp; user.getHeight() &gt; <span class="number">180</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否所有用户年龄都小于35岁且身高大于180cm：&quot;</span>);</span><br><span class="line">    System.out.println(allMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试anyMatch()方法</span></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">anyMatch</span> <span class="operator">=</span> userList.stream().anyMatch(<span class="keyword">new</span> <span class="title class_">Predicate</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> user.getAge() &lt; <span class="number">35</span> &amp;&amp; user.getHeight() &gt; <span class="number">180</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(<span class="string">&quot;是否存在年龄小于35岁且身高大于180cm的用户：&quot;</span>);</span><br><span class="line">    System.out.println(anyMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    Stream&lt;User&gt; build = Stream.&lt;User&gt;builder()</span><br><span class="line">            .add(User.builder().username(<span class="string">&quot;a&quot;</span>).age(<span class="number">1</span>).height(<span class="number">165.0</span>).weight(<span class="number">100.0</span>).build())</span><br><span class="line">            .add(User.builder().username(<span class="string">&quot;b&quot;</span>).age(<span class="number">2</span>).height(<span class="number">175.0</span>).weight(<span class="number">110.0</span>).build())</span><br><span class="line">            .add(User.builder().username(<span class="string">&quot;c&quot;</span>).age(<span class="number">3</span>).height(<span class="number">185.0</span>).weight(<span class="number">120.0</span>).build())</span><br><span class="line">            .build();</span><br><span class="line">    System.out.println(<span class="string">&quot;使用builder()方法构建流：&quot;</span>);</span><br><span class="line">    build.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试collect()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;User&gt;&gt; collect = userList.stream().collect(Collectors.groupingBy(<span class="keyword">new</span> <span class="title class_">Function</span>&lt;User, Integer&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Integer <span class="title function_">apply</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> user.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;根据年龄进行分组：&quot;</span>);</span><br><span class="line">    System.out.println(collect);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试collect()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;User&gt;&gt; collect1 = userList.stream().collect(</span><br><span class="line">            <span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;Map&lt;Integer, List&lt;User&gt;&gt;&gt;() &#123;</span><br><span class="line">                <span class="meta">@Override</span></span><br><span class="line">                <span class="keyword">public</span> Map&lt;Integer, List&lt;User&gt;&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">                    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            <span class="keyword">new</span> <span class="title class_">BiConsumer</span>&lt;Map&lt;Integer, List&lt;User&gt;&gt;, User&gt;() &#123;</span><br><span class="line">                <span class="meta">@Override</span></span><br><span class="line">                <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(Map&lt;Integer, List&lt;User&gt;&gt; map, User user)</span> &#123;</span><br><span class="line">                    map.put(user.getAge(), <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;User&gt;() &#123;&#123;</span><br><span class="line">                        add(user);</span><br><span class="line">                    &#125;&#125;);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;,</span><br><span class="line">            <span class="keyword">new</span> <span class="title class_">BiConsumer</span>&lt;Map&lt;Integer, List&lt;User&gt;&gt;, Map&lt;Integer, List&lt;User&gt;&gt;&gt;() &#123;</span><br><span class="line">                <span class="meta">@Override</span></span><br><span class="line">                <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(Map&lt;Integer, List&lt;User&gt;&gt; map1, Map&lt;Integer, List&lt;User&gt;&gt; map2)</span> &#123;</span><br><span class="line">                    map1.putAll(map2);</span><br><span class="line">                &#125;</span><br><span class="line">            &#125;</span><br><span class="line">    );</span><br><span class="line">    System.out.println(<span class="string">&quot;根据年龄进行分组：&quot;</span>);</span><br><span class="line">    System.out.println(collect1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试concat()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印两个连接起来的Stream元素：&quot;</span>);</span><br><span class="line">    Stream.concat(userList.stream(), Stream.of(User.builder().username(<span class="string">&quot;lastuser&quot;</span>).age(<span class="number">1</span>).height(<span class="number">165.0</span>).weight(<span class="number">100.0</span>).build())).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试count()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;统计用户数量：&quot;</span>);</span><br><span class="line">    <span class="type">long</span> <span class="variable">count</span> <span class="operator">=</span> userList.stream().count();</span><br><span class="line">    System.out.println(count);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试distinct()方法 根据Object.equals(Object)方法去重，对象需要重写equals方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;去重后打印：&quot;</span>);</span><br><span class="line">    userList.stream().distinct().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试empty()方法</span></span><br><span class="line">    Stream&lt;User&gt; empty = Stream.empty();</span><br><span class="line">    System.out.println(<span class="string">&quot;返回引用对象为User类型的空流：&quot;</span>);</span><br><span class="line">    System.out.println(empty);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试filter()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;过滤掉年龄大于等于35岁的用户：&quot;</span>);</span><br><span class="line">    userList.stream().filter(<span class="keyword">new</span> <span class="title class_">Predicate</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> user.getAge() &lt; <span class="number">35</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findAny()方法，返回流中任意的一个元素，结果不稳定</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user</span> <span class="operator">=</span> userList.stream().findAny().orElse(User.builder().build());</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中任意一个元素：&quot;</span>);</span><br><span class="line">    System.out.println(user);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试findFirst()方法，返回流中第一个元素，结果稳定</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">user1</span> <span class="operator">=</span> userList.stream().findAny().orElse(User.builder().build());</span><br><span class="line">    System.out.println(<span class="string">&quot;返回流中首个元素：&quot;</span>);</span><br><span class="line">    System.out.println(user1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试flatMap()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;测试flatMap()方法，每人年龄+10岁：&quot;</span>);</span><br><span class="line">    userList.stream().flatMap(<span class="keyword">new</span> <span class="title class_">Function</span>&lt;User, Stream&lt;?&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Stream&lt;?&gt; apply(User user) &#123;</span><br><span class="line">            user.setAge(user.getAge() + <span class="number">10</span>);</span><br><span class="line">            <span class="keyword">return</span> Stream.of(user);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试flatMapToDouble()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;测试flatMapToDouble()方法：&quot;</span>);</span><br><span class="line">    userList.stream().flatMapToDouble(<span class="keyword">new</span> <span class="title class_">Function</span>&lt;User, DoubleStream&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> DoubleStream <span class="title function_">apply</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> DoubleStream.of(user.getHeight());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试flatMapToInt()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;flatMapToInt()方法：&quot;</span>);</span><br><span class="line">    userList.stream().flatMapToInt(<span class="keyword">new</span> <span class="title class_">Function</span>&lt;User, IntStream&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> IntStream <span class="title function_">apply</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> IntStream.of(user.getAge());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试flatMapToLong()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;flatMapToLong()方法：&quot;</span>);</span><br><span class="line">    userList.stream().flatMapToLong(<span class="keyword">new</span> <span class="title class_">Function</span>&lt;User, LongStream&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> LongStream <span class="title function_">apply</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> LongStream.of(user.getAge());</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEach()方法，不保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试forEachOrdered()方法，保证顺序</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印每个年龄：&quot;</span>);</span><br><span class="line">    userList.parallelStream().forEachOrdered(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试generate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;随机生成10个数字：&quot;</span>);</span><br><span class="line">    <span class="type">Random</span> <span class="variable">random</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Random</span>();</span><br><span class="line">    Object[] objects1 = Stream.&lt;Long&gt;generate(<span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;Long&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Long <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> random.nextLong();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(objects1));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;生成10个等差数：&quot;</span>);</span><br><span class="line">    Object[] objects2 = Stream.iterate(<span class="number">2</span>, <span class="keyword">new</span> <span class="title class_">UnaryOperator</span>&lt;Integer&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Integer <span class="title function_">apply</span><span class="params">(Integer op)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> op + <span class="number">2</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).limit(<span class="number">10</span>).toArray();</span><br><span class="line">    System.out.println(Arrays.toString(objects2));</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试iterate()方法</span></span><br><span class="line">    Iterator&lt;User&gt; iterator = userList.stream().iterator();</span><br><span class="line">    System.out.println(<span class="string">&quot;通过iterate打印元素：&quot;</span>);</span><br><span class="line">    <span class="keyword">while</span> (iterator.hasNext()) &#123;</span><br><span class="line">        System.out.println(iterator.next());</span><br><span class="line">    &#125;</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试limit()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求前三个用户：&quot;</span>);</span><br><span class="line">    userList.stream().limit(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试map()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;将所有年龄+20岁：&quot;</span>);</span><br><span class="line">    userList.stream().map(<span class="keyword">new</span> <span class="title class_">Function</span>&lt;User, User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            user.setAge(user.getAge() + <span class="number">20</span>);</span><br><span class="line">            <span class="keyword">return</span> user;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToDouble()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;获取所有用户身高：&quot;</span>);</span><br><span class="line">    userList.stream().mapToDouble(<span class="keyword">new</span> <span class="title class_">ToDoubleFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(User value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value.getHeight();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToInt()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;获取所有用户年龄：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(<span class="keyword">new</span> <span class="title class_">ToIntFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(User value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToInt()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;获取所有用户年龄：&quot;</span>);</span><br><span class="line">    userList.stream().mapToInt(<span class="keyword">new</span> <span class="title class_">ToIntFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(User value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapToLong()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;获取所有用户年龄：&quot;</span>);</span><br><span class="line">    userList.stream().mapToLong(<span class="keyword">new</span> <span class="title class_">ToLongFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(User value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试max()方法</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">max</span> <span class="operator">=</span> userList.stream().max(<span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(User o1, User o2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> o1.getAge() - o2.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).orElse(User.builder().age(-<span class="number">1</span>).build());</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最大的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(max.getAge());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试min()方法</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">min</span> <span class="operator">=</span> userList.stream().min(<span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(User o1, User o2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> o1.getAge() - o2.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).orElse(User.builder().age(-<span class="number">1</span>).build());</span><br><span class="line">    System.out.println(<span class="string">&quot;获取最小的年龄：&quot;</span>);</span><br><span class="line">    System.out.println(min.getAge());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试noneMatch()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回是否没有年龄大于100的用户：&quot;</span>);</span><br><span class="line">    <span class="type">boolean</span> <span class="variable">noneMatch</span> <span class="operator">=</span> userList.stream().noneMatch(<span class="keyword">new</span> <span class="title class_">Predicate</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> user.getAge() &gt; <span class="number">100</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(noneMatch);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的多个元素序列：&quot;</span>);</span><br><span class="line">    Stream.of(</span><br><span class="line">            User.builder().username(<span class="string">&quot;zhangsan&quot;</span>).age(<span class="number">13</span>).height(<span class="number">163.0</span>).weight(<span class="number">45.0</span>).build(),</span><br><span class="line">            User.builder().username(<span class="string">&quot;lisi&quot;</span>).age(<span class="number">13</span>).height(<span class="number">163.0</span>).weight(<span class="number">45.0</span>).build(),</span><br><span class="line">            User.builder().username(<span class="string">&quot;wangwu&quot;</span>).age(<span class="number">13</span>).height(<span class="number">163.0</span>).weight(<span class="number">45.0</span>).build(),</span><br><span class="line">            User.builder().username(<span class="string">&quot;zhaoliu&quot;</span>).age(<span class="number">13</span>).height(<span class="number">163.0</span>).weight(<span class="number">45.0</span>).build()</span><br><span class="line">    ).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试of()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印生成的单个元素序列：&quot;</span>);</span><br><span class="line">    Stream.of(User.builder().username(<span class="string">&quot;zhangsan&quot;</span>).age(<span class="number">13</span>).height(<span class="number">163.0</span>).weight(<span class="number">45.0</span>).build()).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试parallel()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回并发流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.stream().parallel());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试peek()方法，是一个中间操作，主要用于调试</span></span><br><span class="line">    System.out.println(<span class="string">&quot;打印流中的每个元素：&quot;</span>);</span><br><span class="line">    userList.stream().peek(<span class="keyword">new</span> <span class="title class_">Consumer</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">accept</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            System.out.println(user);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).count();</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为流的第一个元素</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    Optional&lt;User&gt; reduce = userList.stream().reduce(<span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(User user, User user2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> User.builder().age(user.getAge() + user2.getAge()).build();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(reduce.get());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reduce()方法，首个元素为identity（即第一个参数）</span></span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    <span class="type">User</span> <span class="variable">reduce1</span> <span class="operator">=</span> userList.stream().reduce(User.builder().age(<span class="number">0</span>).build(), <span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(User user, User user2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> User.builder().age(user.getAge() + user2.getAge()).build();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(reduce1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sequential()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;返回顺序流：&quot;</span>);</span><br><span class="line">    System.out.println(userList.parallelStream().sequential());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试skip()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;跳过前三个元素：&quot;</span>);</span><br><span class="line">    userList.stream().skip(<span class="number">3</span>).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试sorted()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;按年龄大小排序：&quot;</span>);</span><br><span class="line">    userList.stream().sorted(<span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(User o1, User o2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> o1.getAge() - o2.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;).forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toArray()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;转换为User数组：&quot;</span>);</span><br><span class="line">    Object[] objects = userList.stream().toArray();</span><br><span class="line">    System.out.println(Arrays.toString(objects));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toArray()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;转换为User数组：&quot;</span>);</span><br><span class="line">    User[] as = userList.stream().&lt;User&gt;toArray(<span class="keyword">new</span> <span class="title class_">IntFunction</span>&lt;User[]&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User[] apply(<span class="type">int</span> value) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">User</span>[value];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">    System.out.println(Arrays.toString(as));</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br></pre></td><td class="code"><pre><span class="line">是否所有用户年龄都小于35岁且身高大于180cm：</span><br><span class="line">false</span><br><span class="line">-----------------------</span><br><span class="line">是否存在年龄小于35岁且身高大于180cm的用户：</span><br><span class="line">false</span><br><span class="line">-----------------------</span><br><span class="line">使用builder()方法构建流：</span><br><span class="line">User(age=1, height=165.0, weight=100.0, username=a)</span><br><span class="line">User(age=2, height=175.0, weight=110.0, username=b)</span><br><span class="line">User(age=3, height=185.0, weight=120.0, username=c)</span><br><span class="line">-----------------------</span><br><span class="line">根据年龄进行分组：</span><br><span class="line">&#123;32=[User(age=32, height=180.0, weight=79.0, username=wangwu)], 18=[User(age=18, height=160.0, weight=50.0, username=zhangsan)], 21=[User(age=21, height=162.0, weight=70.0, username=zhangsan), User(age=21, height=169.0, weight=72.0, username=zhaoliu), User(age=21, height=169.0, weight=72.0, username=zhaoliu)], 28=[User(age=28, height=172.0, weight=56.0, username=lisi)]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">根据年龄进行分组：</span><br><span class="line">&#123;32=[User(age=32, height=180.0, weight=79.0, username=wangwu)], 18=[User(age=18, height=160.0, weight=50.0, username=zhangsan)], 21=[User(age=21, height=169.0, weight=72.0, username=zhaoliu)], 28=[User(age=28, height=172.0, weight=56.0, username=lisi)]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">打印两个连接起来的Stream元素：</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=28, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=32, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=21, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=21, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=21, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=1, height=165.0, weight=100.0, username=lastuser)</span><br><span class="line">-----------------------</span><br><span class="line">统计用户数量：</span><br><span class="line">6</span><br><span class="line">-----------------------</span><br><span class="line">去重后打印：</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=28, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=32, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=21, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=21, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">返回引用对象为User类型的空流：</span><br><span class="line">java.util.stream.ReferencePipeline$Head@312b1dae</span><br><span class="line">-----------------------</span><br><span class="line">过滤掉年龄大于等于35岁的用户：</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=28, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=32, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=21, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=21, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=21, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">返回流中任意一个元素：</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">-----------------------</span><br><span class="line">返回流中首个元素：</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">-----------------------</span><br><span class="line">测试flatMap()方法，每人年龄+10岁：</span><br><span class="line">User(age=28, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=38, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=42, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=31, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">测试flatMapToDouble()方法：</span><br><span class="line">160.0</span><br><span class="line">172.0</span><br><span class="line">180.0</span><br><span class="line">162.0</span><br><span class="line">169.0</span><br><span class="line">169.0</span><br><span class="line">-----------------------</span><br><span class="line">flatMapToInt()方法：</span><br><span class="line">28</span><br><span class="line">38</span><br><span class="line">42</span><br><span class="line">31</span><br><span class="line">31</span><br><span class="line">31</span><br><span class="line">-----------------------</span><br><span class="line">flatMapToLong()方法：</span><br><span class="line">28</span><br><span class="line">38</span><br><span class="line">42</span><br><span class="line">31</span><br><span class="line">31</span><br><span class="line">31</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">User(age=31, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=42, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=38, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=28, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">-----------------------</span><br><span class="line">打印每个年龄：</span><br><span class="line">User(age=28, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=38, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=42, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=31, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">随机生成10个数字：</span><br><span class="line">[1615966171823288384, -7259602941028351229, -8753231398543192414, -5934361928967435957, -8657526691897631118, 3475987589712582957, -7014446858359418156, -2699681240803486737, -5644722432246409033, -5677493669317247050]</span><br><span class="line">-----------------------</span><br><span class="line">生成10个等差数：</span><br><span class="line">[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]</span><br><span class="line">通过iterate打印元素：</span><br><span class="line">User(age=28, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=38, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=42, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=31, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=31, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">求前三个用户：</span><br><span class="line">User(age=28, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=38, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=42, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">-----------------------</span><br><span class="line">将所有年龄+20岁：</span><br><span class="line">User(age=48, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=58, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=62, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=51, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">获取所有用户身高：</span><br><span class="line">160.0</span><br><span class="line">172.0</span><br><span class="line">180.0</span><br><span class="line">162.0</span><br><span class="line">169.0</span><br><span class="line">169.0</span><br><span class="line">-----------------------</span><br><span class="line">获取所有用户年龄：</span><br><span class="line">48</span><br><span class="line">58</span><br><span class="line">62</span><br><span class="line">51</span><br><span class="line">51</span><br><span class="line">51</span><br><span class="line">-----------------------</span><br><span class="line">获取所有用户年龄：</span><br><span class="line">48</span><br><span class="line">58</span><br><span class="line">62</span><br><span class="line">51</span><br><span class="line">51</span><br><span class="line">51</span><br><span class="line">-----------------------</span><br><span class="line">获取所有用户年龄：</span><br><span class="line">48</span><br><span class="line">58</span><br><span class="line">62</span><br><span class="line">51</span><br><span class="line">51</span><br><span class="line">51</span><br><span class="line">-----------------------</span><br><span class="line">获取最大的年龄：</span><br><span class="line">62</span><br><span class="line">-----------------------</span><br><span class="line">获取最小的年龄：</span><br><span class="line">48</span><br><span class="line">-----------------------</span><br><span class="line">返回是否没有年龄大于100的用户：</span><br><span class="line">true</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的多个元素序列：</span><br><span class="line">User(age=13, height=163.0, weight=45.0, username=zhangsan)</span><br><span class="line">User(age=13, height=163.0, weight=45.0, username=lisi)</span><br><span class="line">User(age=13, height=163.0, weight=45.0, username=wangwu)</span><br><span class="line">User(age=13, height=163.0, weight=45.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">打印生成的单个元素序列：</span><br><span class="line">User(age=13, height=163.0, weight=45.0, username=zhangsan)</span><br><span class="line">-----------------------</span><br><span class="line">返回并发流：</span><br><span class="line">java.util.stream.ReferencePipeline$Head@49c2faae</span><br><span class="line">-----------------------</span><br><span class="line">打印流中的每个元素：</span><br><span class="line">User(age=48, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=58, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=62, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">User(age=51, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">User(age=321, height=null, weight=null, username=null)</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">User(age=321, height=null, weight=null, username=null)</span><br><span class="line">-----------------------</span><br><span class="line">返回顺序流：</span><br><span class="line">java.util.stream.ReferencePipeline$Head@20ad9418</span><br><span class="line">-----------------------</span><br><span class="line">跳过前三个元素：</span><br><span class="line">User(age=51, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">-----------------------</span><br><span class="line">按年龄大小排序：</span><br><span class="line">User(age=48, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">User(age=51, height=162.0, weight=70.0, username=zhangsan)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=51, height=169.0, weight=72.0, username=zhaoliu)</span><br><span class="line">User(age=58, height=172.0, weight=56.0, username=lisi)</span><br><span class="line">User(age=62, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">-----------------------</span><br><span class="line">转换为User数组：</span><br><span class="line">[User(age=48, height=160.0, weight=50.0, username=zhangsan), User(age=58, height=172.0, weight=56.0, username=lisi), User(age=62, height=180.0, weight=79.0, username=wangwu), User(age=51, height=162.0, weight=70.0, username=zhangsan), User(age=51, height=169.0, weight=72.0, username=zhaoliu), User(age=51, height=169.0, weight=72.0, username=zhaoliu)]</span><br><span class="line">-----------------------</span><br><span class="line">转换为User数组：</span><br><span class="line">[User(age=48, height=160.0, weight=50.0, username=zhangsan), User(age=58, height=172.0, weight=56.0, username=lisi), User(age=62, height=180.0, weight=79.0, username=wangwu), User(age=51, height=162.0, weight=70.0, username=zhangsan), User(age=51, height=169.0, weight=72.0, username=zhaoliu), User(age=51, height=169.0, weight=72.0, username=zhaoliu)]</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<h3 id="Stream-Builder"><a href="#Stream-Builder" class="headerlink" title="Stream.Builder"></a>Stream.Builder</h3><p>Stream.Builder是Stream是构建器，Stream.Builder具有生命周期，其从构建阶段开始，在该阶段期间可以添加元素，然后转换到内置阶段，之后可能不添加元素。构建阶段从调用build()方法开始，它创建一个有序流，其元素是添加到流构建器的元素，按照它们被添加的顺序。</p>
<p>Stream.Builder提供以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>void</td>
<td>accept(long t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>default LongStream.Builder</td>
<td>add(long t)</td>
<td>向要构建的流添加元素。</td>
</tr>
<tr>
<td>LongStream</td>
<td>build()</td>
<td>构建流，将此构建器转换为内置状态。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test10</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试builder()方法</span></span><br><span class="line">    <span class="type">Stream</span> <span class="variable">build</span> <span class="operator">=</span> Stream.&lt;User&gt;builder()</span><br><span class="line">            .add(User.builder().username(<span class="string">&quot;zhangsan&quot;</span>).build())</span><br><span class="line">            .add(User.builder().username(<span class="string">&quot;lisi&quot;</span>).build())</span><br><span class="line">            .add(User.builder().username(<span class="string">&quot;wangwu&quot;</span>).build())</span><br><span class="line">            .add(User.builder().username(<span class="string">&quot;zhaoliu&quot;</span>).build())</span><br><span class="line">            .build();</span><br><span class="line">    System.out.println(<span class="string">&quot;遍历通过builder()方法创建的Stream元素：&quot;</span>);</span><br><span class="line">    build.forEach(System.out::println);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">遍历通过builder()方法创建的Stream元素：</span><br><span class="line">User(age=null, height=null, weight=null, username=zhangsan)</span><br><span class="line">User(age=null, height=null, weight=null, username=lisi)</span><br><span class="line">User(age=null, height=null, weight=null, username=wangwu)</span><br><span class="line">User(age=null, height=null, weight=null, username=zhaoliu)</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<p>Stream.Builderd的accept(double t)方法只在StreamBuilderImpl中有实现，StreamBuilderImpl在两个地方有用法：</p>
<ol>
<li>Stream的builder()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回StreamBuilderImpl实例</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span>&lt;T&gt; Builder&lt;T&gt; <span class="title function_">builder</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">Streams</span>.StreamBuilderImpl&lt;&gt;();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<ol start="2">
<li>Stream的of()方法：</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">* 返回具有单个元素的Stream </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span>&lt;T&gt; Stream&lt;T&gt; <span class="title function_">of</span><span class="params">(T t)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> StreamSupport.stream(<span class="keyword">new</span> <span class="title class_">Streams</span>.StreamBuilderImpl&lt;&gt;(t), <span class="literal">false</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="类"><a href="#类" class="headerlink" title="类"></a>类</h2><h3 id="Collectors"><a href="#Collectors" class="headerlink" title="Collectors"></a>Collectors</h3><p>Collectors是一个工具类，其中实现了很多的Collect操作供我们使用。</p>
<p>Collectors提供以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>static <T> Collector&lt;T,?,Double&gt;</td>
<td>averagingDouble(ToDoubleFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ，它产生应用于输入元素的双值函数的算术平均值。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Double&gt;</td>
<td>averagingInt(ToIntFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ，它产生应用于输入元素的整数值函数的算术平均值。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Double&gt;</td>
<td>averagingLong(ToLongFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ，它产生应用于输入元素的长值函数的算术平均值。</td>
</tr>
<tr>
<td>static &lt;T,A,R,RR&gt; Collector&lt;T,A,RR&gt;</td>
<td>collectingAndThen(Collector&lt;T,A,R&gt; downstream, Function&lt;R,RR&gt; finisher)</td>
<td>适应 Collector进行额外的整理转换。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Long&gt;</td>
<td>counting()</td>
<td>返回 Collector类型的接受元件 T计数输入元件的数量。</td>
</tr>
<tr>
<td>static &lt;T,K&gt; Collector&lt;T,?,Map&lt;K,List<T>&gt;&gt;</td>
<td>groupingBy(Function&lt;? super T,? extends K&gt; classifier)</td>
<td>返回 Collector “由基团”上的类型的输入元件操作实现 T ，根据分类功能分组元素，并且在返回的结果 Map 。</td>
</tr>
<tr>
<td>static &lt;T,K,A,D&gt; Collector&lt;T,?,Map&lt;K,D&gt;&gt;</td>
<td>groupingBy(Function&lt;? super T,? extends K&gt; classifier, Collector&lt;? super T,A,D&gt; downstream)</td>
<td>返回 Collector “由基团”上的类型的输入元件操作实现级联 T ，根据分类功能分组元素，然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。</td>
</tr>
<tr>
<td>static &lt;T,K,D,A,M extends Map&lt;K,D&gt;&gt; Collector&lt;T,?,M&gt;</td>
<td>groupingBy(Function&lt;? super T,? extends K&gt; classifier, Supplier<M> mapFactory, Collector&lt;? super T,A,D&gt; downstream)</td>
<td>返回 Collector “由基团”上的类型的输入元件操作实现级联 T ，根据分类功能分组元素，然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。</td>
</tr>
<tr>
<td>static &lt;T,K&gt; Collector&lt;T,?,ConcurrentMap&lt;K,List<T>&gt;&gt;</td>
<td>groupingByConcurrent(Function&lt;? super T,? extends K&gt; classifier)</td>
<td>返回一个并发 Collector “由基团”上的类型的输入元件操作实现 T ，根据分类功能分组元素。</td>
</tr>
<tr>
<td>static &lt;T,K,A,D&gt; Collector&lt;T,?,ConcurrentMap&lt;K,D&gt;&gt;</td>
<td>groupingByConcurrent(Function&lt;? super T,? extends K&gt; classifier, Collector&lt;? super T,A,D&gt; downstream)</td>
<td>返回一个并发 Collector “由基团”上的类型的输入元件操作实现级联 T ，根据分类功能分组元素，然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。</td>
</tr>
<tr>
<td>static &lt;T,K,A,D,M extends ConcurrentMap&lt;K,D&gt;&gt; Collector&lt;T,?,M&gt;</td>
<td>groupingByConcurrent(Function&lt;? super T,? extends K&gt; classifier, Supplier<M> mapFactory, Collector&lt;? super T,A,D&gt; downstream)</td>
<td>返回一个并发 Collector “由基团”上的类型的输入元件操作实现级联 T ，根据分类功能分组元素，然后使用下游的指定执行与给定键相关联的值的归约运算 Collector 。</td>
</tr>
<tr>
<td>static Collector&lt;CharSequence,?,String&gt;</td>
<td>joining()</td>
<td>返回一个 Collector ，按照遇到的顺序将输入元素连接到一个 String中。</td>
</tr>
<tr>
<td>static Collector&lt;CharSequence,?,String&gt;</td>
<td>joining(CharSequence delimiter)</td>
<td>返回一个 Collector ，按照遇到的顺序连接由指定的分隔符分隔的输入元素。</td>
</tr>
<tr>
<td>static Collector&lt;CharSequence,?,String&gt;</td>
<td>joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)</td>
<td>返回一个 Collector ，它将按照指定的 Collector分隔的输入元素与指定的前缀和后缀进行连接。</td>
</tr>
<tr>
<td>static &lt;T,U,A,R&gt; Collector&lt;T,?,R&gt;</td>
<td>mapping(Function&lt;? super T,? extends U&gt; mapper, Collector&lt;? super U,A,R&gt; downstream)</td>
<td>适应一个 Collector类型的接受元件 U至类型的一个接受元件 T通过积累前应用映射函数到每个输入元素。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Optional<T>&gt;</td>
<td>maxBy(Comparator&lt;? super T&gt; comparator)</td>
<td>返回一个 Collector ，它根据给出的 Comparator产生最大元素，描述为 Optional<T> 。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Optional<T>&gt;</td>
<td>minBy(Comparator&lt;? super T&gt; comparator)</td>
<td>返回一个 Collector ，根据给出的 Comparator产生最小元素，描述为 Optional<T> 。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Map&lt;Boolean,List<T>&gt;&gt;</td>
<td>partitioningBy(Predicate&lt;? super T&gt; predicate)</td>
<td>返回一个 Collector ，根据Predicate对输入元素进行 Predicate ，并将它们组织成 Map&lt;Boolean, List<T>&gt;。</td>
</tr>
<tr>
<td>static &lt;T,D,A&gt; Collector&lt;T,?,Map&lt;Boolean,D&gt;&gt;</td>
<td>partitioningBy(Predicate&lt;? super T&gt; predicate, Collector&lt;? super T,A,D&gt; downstream)</td>
<td>返回一个 Collector ，它根据Predicate对输入元素进行 Predicate ，根据另一个 Collector减少每个分区的值，并将其组织成 Map&lt;Boolean, D&gt; ，其值是下游缩减的结果。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Optional<T>&gt;</td>
<td>reducing(BinaryOperator<T> op)</td>
<td>返回一个 Collector ，它在指定的 Collector下执行其输入元素的 BinaryOperator 。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,T&gt;</td>
<td>reducing(T identity, BinaryOperator<T> op)</td>
<td>返回 Collector执行下一个指定的减少其输入元件的 BinaryOperator使用所提供的身份。</td>
</tr>
<tr>
<td>static &lt;T,U&gt; Collector&lt;T,?,U&gt;</td>
<td>reducing(U identity, Function&lt;? super T,? extends U&gt; mapper, BinaryOperator<U> op)</td>
<td>返回一个 Collector ，它在指定的映射函数和 BinaryOperator下执行其输入元素的 BinaryOperator。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,DoubleSummaryStatistics&gt;</td>
<td>summarizingDouble(ToDoubleFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ， double生产映射函数应用于每个输入元素，并返回结果值的汇总统计信息。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,IntSummaryStatistics&gt;</td>
<td>summarizingInt(ToIntFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ， int生产映射函数应用于每个输入元素，并返回结果值的汇总统计信息。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,LongSummaryStatistics&gt;</td>
<td>summarizingLong(ToLongFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ， long生产映射函数应用于每个输入元素，并返回结果值的汇总统计信息。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Double&gt;</td>
<td>summingDouble(ToDoubleFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ，它产生应用于输入元素的双值函数的和。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Integer&gt;</td>
<td>summingInt(ToIntFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ，它产生应用于输入元素的整数值函数的和。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Long&gt;</td>
<td>summingLong(ToLongFunction&lt;? super T&gt; mapper)</td>
<td>返回一个 Collector ，它产生应用于输入元素的长值函数的和。</td>
</tr>
<tr>
<td>static &lt;T,C extends Collection<T>&gt; Collector&lt;T,?,C&gt;</td>
<td>toCollection(Supplier<C> collectionFactory)</td>
<td>返回一个 Collector ，按照遇到的顺序将输入元素累加到一个新的 Collection中。</td>
</tr>
<tr>
<td>static &lt;T,K,U&gt; Collector&lt;T,?,ConcurrentMap&lt;K,U&gt;&gt;</td>
<td>toConcurrentMap(Function&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper)</td>
<td>返回一个并发的 Collector ，它将元素累加到 ConcurrentMap ，其键和值是将所提供的映射函数应用于输入元素的结果。</td>
</tr>
<tr>
<td>static &lt;T,K,U&gt; Collector&lt;T,?,ConcurrentMap&lt;K,U&gt;&gt;</td>
<td>toConcurrentMap(Function&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper, BinaryOperator<U> mergeFunction)</td>
<td>返回一个并发的 Collector ，它将元素累加到一个 ConcurrentMap ，其键和值是将提供的映射函数应用于输入元素的结果。</td>
</tr>
<tr>
<td>static &lt;T,K,U,M extends ConcurrentMap&lt;K,U&gt;&gt; Collector&lt;T,?,M&gt;</td>
<td>toConcurrentMap(Function&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)</td>
<td>返回一个并发的 Collector ，它将元素累加到一个 ConcurrentMap ，其键和值是将所提供的映射函数应用于输入元素的结果。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,List<T>&gt;</td>
<td>toList()</td>
<td>返回一个 Collector ，它将输入元素 List到一个新的 List。</td>
</tr>
<tr>
<td>static &lt;T,K,U&gt; Collector&lt;T,?,Map&lt;K,U&gt;&gt;</td>
<td>toMap(Function&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper)</td>
<td>返回一个 Collector ，它将元素累加到一个 Map ，其键和值是将所提供的映射函数应用于输入元素的结果。</td>
</tr>
<tr>
<td>static &lt;T,K,U&gt; Collector&lt;T,?,Map&lt;K,U&gt;&gt;</td>
<td>toMap(Function&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper, BinaryOperator<U> mergeFunction)</td>
<td>返回一个 Collector ，它将元素累加到 Map ，其键和值是将提供的映射函数应用于输入元素的结果。</td>
</tr>
<tr>
<td>static &lt;T,K,U,M extends Map&lt;K,U&gt;&gt; Collector&lt;T,?,M&gt;</td>
<td>toMap(Function&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)</td>
<td>返回一个 Collector ，它将元素累加到一个 Map ，其键和值是将所提供的映射函数应用于输入元素的结果。</td>
</tr>
<tr>
<td>static <T> Collector&lt;T,?,Set<T>&gt;</td>
<td>toSet()</td>
<td>返回一个 Collector ，将输入元素 Set到一个新的 Set。</td>
</tr>
</tbody></table>
<p>测试方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">test11</span><span class="params">(List&lt;User&gt; userList)</span> &#123;</span><br><span class="line">    <span class="comment">// 测试averagingDouble()方法</span></span><br><span class="line">    <span class="type">Double</span> <span class="variable">collect1</span> <span class="operator">=</span> userList.stream().collect(Collectors.averagingDouble(<span class="keyword">new</span> <span class="title class_">ToDoubleFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">double</span> <span class="title function_">applyAsDouble</span><span class="params">(User value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value.getHeight();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求用户平均身高：&quot;</span>);</span><br><span class="line">    System.out.println(collect1);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试averagingInt()方法</span></span><br><span class="line">    <span class="type">Double</span> <span class="variable">collect2</span> <span class="operator">=</span> userList.stream().collect(Collectors.averagingInt(<span class="keyword">new</span> <span class="title class_">ToIntFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">applyAsInt</span><span class="params">(User value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求用户平均年龄：&quot;</span>);</span><br><span class="line">    System.out.println(collect2);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试averagingLong()方法</span></span><br><span class="line">    <span class="type">Double</span> <span class="variable">collect3</span> <span class="operator">=</span> userList.stream().collect(Collectors.averagingLong(<span class="keyword">new</span> <span class="title class_">ToLongFunction</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">long</span> <span class="title function_">applyAsLong</span><span class="params">(User value)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> value.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求用户平均年龄：&quot;</span>);</span><br><span class="line">    System.out.println(collect3);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试collectingAndThen()方法</span></span><br><span class="line">    System.out.println(<span class="string">&quot;先根据年龄分组，在统计分组数量：&quot;</span>);</span><br><span class="line">    <span class="type">Integer</span> <span class="variable">collect</span> <span class="operator">=</span> userList.stream().collect(Collectors.collectingAndThen(Collectors.groupingBy(User::getAge), Map::size));</span><br><span class="line">    System.out.println(collect);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试counting()方法</span></span><br><span class="line">    <span class="type">Long</span> <span class="variable">collect4</span> <span class="operator">=</span> userList.stream().collect(Collectors.counting());</span><br><span class="line">    System.out.println(<span class="string">&quot;统计用户数量：&quot;</span>);</span><br><span class="line">    System.out.println(collect4);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试groupingBy()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;User&gt;&gt; collect5 = userList.stream().collect(Collectors.groupingBy(User::getAge));</span><br><span class="line">    System.out.println(<span class="string">&quot;根据用户年龄分组：&quot;</span>);</span><br><span class="line">    System.out.println(collect5);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试groupingBy()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;String&gt;&gt; collect6 = userList.stream().collect(Collectors.groupingBy(User::getAge, Collectors.mapping(User::getUsername, Collectors.toList())));</span><br><span class="line">    System.out.println(<span class="string">&quot;根据用户年龄分组，再获取姓名列表：&quot;</span>);</span><br><span class="line">    System.out.println(collect6);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试groupingBy()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;String&gt;&gt; collect7 = userList.stream().collect(Collectors.groupingBy(User::getAge, HashMap::<span class="keyword">new</span>, Collectors.mapping(User::getUsername, Collectors.toList())));</span><br><span class="line">    System.out.println(<span class="string">&quot;根据用户年龄分组，再获取姓名列表：&quot;</span>);</span><br><span class="line">    System.out.println(collect7);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试groupingByConcurrent()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;User&gt;&gt; collect8 = userList.stream().collect(Collectors.groupingByConcurrent(User::getAge));</span><br><span class="line">    System.out.println(<span class="string">&quot;根据用户年龄分组：&quot;</span>);</span><br><span class="line">    System.out.println(collect8);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试groupingByConcurrent()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;String&gt;&gt; collect9 = userList.stream().collect(Collectors.groupingByConcurrent(User::getAge, Collectors.mapping(User::getUsername, Collectors.toList())));</span><br><span class="line">    System.out.println(<span class="string">&quot;根据用户年龄分组，再获取姓名列表：&quot;</span>);</span><br><span class="line">    System.out.println(collect9);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试groupingByConcurrent()方法</span></span><br><span class="line">    Map&lt;Integer, List&lt;String&gt;&gt; collect10 = userList.stream().collect(Collectors.groupingByConcurrent(User::getAge, ConcurrentHashMap::<span class="keyword">new</span>, Collectors.mapping(User::getUsername, Collectors.toList())));</span><br><span class="line">    System.out.println(<span class="string">&quot;根据用户年龄分组，再获取姓名列表：&quot;</span>);</span><br><span class="line">    System.out.println(collect10);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试joining()方法</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">collect11</span> <span class="operator">=</span> userList.stream().map(User::getUsername).collect(Collectors.joining());</span><br><span class="line">    System.out.println(<span class="string">&quot;输出年龄拼接：&quot;</span>);</span><br><span class="line">    System.out.println(collect11);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试joining()方法</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">collect12</span> <span class="operator">=</span> userList.stream().map(User::getUsername).collect(Collectors.joining(<span class="string">&quot;,&quot;</span>));</span><br><span class="line">    System.out.println(<span class="string">&quot;输出年龄拼接，以逗号分割：&quot;</span>);</span><br><span class="line">    System.out.println(collect12);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试mapping()方法</span></span><br><span class="line">    <span class="type">String</span> <span class="variable">collect13</span> <span class="operator">=</span> userList.stream().collect(Collectors.mapping(User::getUsername, Collectors.joining(<span class="string">&quot;,&quot;</span>)));</span><br><span class="line">    System.out.println(<span class="string">&quot;输出年龄拼接，以逗号分割：&quot;</span>);</span><br><span class="line">    System.out.println(collect13);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试maxBy()方法</span></span><br><span class="line">    Optional&lt;User&gt; collect14 = userList.stream().collect(Collectors.maxBy(<span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(User o1, User o2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> o1.getAge() - o2.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄最大的用户：&quot;</span>);</span><br><span class="line">    System.out.println(collect14.get());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试minBy()方法</span></span><br><span class="line">    Optional&lt;User&gt; collect15 = userList.stream().collect(Collectors.minBy(<span class="keyword">new</span> <span class="title class_">Comparator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">int</span> <span class="title function_">compare</span><span class="params">(User o1, User o2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> o1.getAge() - o2.getAge();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄最小的用户：&quot;</span>);</span><br><span class="line">    System.out.println(collect15.get());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试partitioningBy()方法</span></span><br><span class="line">    Map&lt;Boolean, List&lt;User&gt;&gt; collect16 = userList.stream().collect(Collectors.partitioningBy(<span class="keyword">new</span> <span class="title class_">Predicate</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> user.getAge() &gt; <span class="number">30</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;以年龄30岁为分界线：&quot;</span>);</span><br><span class="line">    System.out.println(collect16);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试partitioningBy()方法</span></span><br><span class="line">    Map&lt;Boolean, Long&gt; collect17 = userList.stream().collect(Collectors.partitioningBy(<span class="keyword">new</span> <span class="title class_">Predicate</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> <span class="type">boolean</span> <span class="title function_">test</span><span class="params">(User user)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> user.getAge() &gt; <span class="number">30</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;, Collectors.counting()));</span><br><span class="line">    System.out.println(<span class="string">&quot;以年龄30岁为分界线：&quot;</span>);</span><br><span class="line">    System.out.println(collect17);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reducing()方法</span></span><br><span class="line">    Optional&lt;User&gt; collect18 = userList.stream().collect(Collectors.reducing(<span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(User user, User user2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> User.builder().age(user.getAge() + user2.getAge()).build();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    System.out.println(collect18.get());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reducing()方法</span></span><br><span class="line">    <span class="type">User</span> <span class="variable">collect19</span> <span class="operator">=</span> userList.stream().collect(Collectors.reducing(User.builder().age(<span class="number">0</span>).build(), <span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;User&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> User <span class="title function_">apply</span><span class="params">(User user, User user2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> User.builder().age(user.getAge() + user2.getAge()).build();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    System.out.println(collect19);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试reducing()方法</span></span><br><span class="line">    <span class="type">Integer</span> <span class="variable">collect20</span> <span class="operator">=</span> userList.stream().collect(</span><br><span class="line">            Collectors.reducing(<span class="number">0</span>,</span><br><span class="line">                    <span class="keyword">new</span> <span class="title class_">Function</span>&lt;User, Integer&gt;() &#123;</span><br><span class="line">                        <span class="meta">@Override</span></span><br><span class="line">                        <span class="keyword">public</span> Integer <span class="title function_">apply</span><span class="params">(User user)</span> &#123;</span><br><span class="line">                            <span class="keyword">return</span> user.getAge();</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;,</span><br><span class="line">                    <span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;Integer&gt;() &#123;</span><br><span class="line">                        <span class="meta">@Override</span></span><br><span class="line">                        <span class="keyword">public</span> Integer <span class="title function_">apply</span><span class="params">(Integer o, Integer o2)</span> &#123;</span><br><span class="line">                            <span class="keyword">return</span> o + o2;</span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;求年龄和：&quot;</span>);</span><br><span class="line">    System.out.println(collect20);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summarizingDouble()方法</span></span><br><span class="line">    <span class="type">DoubleSummaryStatistics</span> <span class="variable">collect21</span> <span class="operator">=</span> userList.stream().collect(Collectors.summarizingDouble(User::getHeight));</span><br><span class="line">    System.out.println(<span class="string">&quot;获取身高统计信息：&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;最高身高：&quot;</span> + collect21.getMax());</span><br><span class="line">    System.out.println(<span class="string">&quot;身高数量：&quot;</span> + collect21.getCount());</span><br><span class="line">    System.out.println(<span class="string">&quot;平均身高：&quot;</span> + collect21.getAverage());</span><br><span class="line">    System.out.println(<span class="string">&quot;最矮身高：&quot;</span> + collect21.getMin());</span><br><span class="line">    System.out.println(<span class="string">&quot;身高总和：&quot;</span> + collect21.getSum());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summarizingInt()方法</span></span><br><span class="line">    <span class="type">IntSummaryStatistics</span> <span class="variable">collect22</span> <span class="operator">=</span> userList.stream().collect(Collectors.summarizingInt(User::getAge));</span><br><span class="line">    System.out.println(<span class="string">&quot;获取年龄统计信息：&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;最大年龄：&quot;</span> + collect22.getMax());</span><br><span class="line">    System.out.println(<span class="string">&quot;年龄数量：&quot;</span> + collect22.getCount());</span><br><span class="line">    System.out.println(<span class="string">&quot;平均年龄：&quot;</span> + collect22.getAverage());</span><br><span class="line">    System.out.println(<span class="string">&quot;最低年龄：&quot;</span> + collect22.getMin());</span><br><span class="line">    System.out.println(<span class="string">&quot;年龄总和：&quot;</span> + collect22.getSum());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summarizingLong()方法</span></span><br><span class="line">    <span class="type">LongSummaryStatistics</span> <span class="variable">collect23</span> <span class="operator">=</span> userList.stream().collect(Collectors.summarizingLong(User::getAge));</span><br><span class="line">    System.out.println(<span class="string">&quot;获取年龄统计信息：&quot;</span>);</span><br><span class="line">    System.out.println(<span class="string">&quot;最大年龄：&quot;</span> + collect23.getMax());</span><br><span class="line">    System.out.println(<span class="string">&quot;年龄数量：&quot;</span> + collect23.getCount());</span><br><span class="line">    System.out.println(<span class="string">&quot;平均年龄：&quot;</span> + collect23.getAverage());</span><br><span class="line">    System.out.println(<span class="string">&quot;最低年龄：&quot;</span> + collect23.getMin());</span><br><span class="line">    System.out.println(<span class="string">&quot;年龄总和：&quot;</span> + collect23.getSum());</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summingDouble()方法</span></span><br><span class="line">    <span class="type">Double</span> <span class="variable">collect24</span> <span class="operator">=</span> userList.stream().collect(Collectors.summingDouble(User::getHeight));</span><br><span class="line">    System.out.println(<span class="string">&quot;身高总和：&quot;</span>);</span><br><span class="line">    System.out.println(collect24);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summingInt()方法</span></span><br><span class="line">    <span class="type">Integer</span> <span class="variable">collect25</span> <span class="operator">=</span> userList.stream().collect(Collectors.summingInt(User::getAge));</span><br><span class="line">    System.out.println(<span class="string">&quot;年龄总和：&quot;</span>);</span><br><span class="line">    System.out.println(collect25);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试summingInt()方法</span></span><br><span class="line">    <span class="type">Long</span> <span class="variable">collect26</span> <span class="operator">=</span> userList.stream().collect(Collectors.summingLong(User::getAge));</span><br><span class="line">    System.out.println(<span class="string">&quot;年龄总和：&quot;</span>);</span><br><span class="line">    System.out.println(collect26);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toCollection()方法</span></span><br><span class="line">    List&lt;User&gt; collect27 = userList.stream().collect(Collectors.&lt;User, List&lt;User&gt;&gt;toCollection(<span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;List&lt;User&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> List&lt;User&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ArrayList</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect27);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toConcurrentMap()方法</span></span><br><span class="line">    ConcurrentMap&lt;Double, String&gt; collect28 = userList.stream().collect(Collectors.&lt;User, Double, String&gt;toConcurrentMap(User::getHeight, User::getUsername));</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为并发集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect28);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toConcurrentMap()方法</span></span><br><span class="line">    ConcurrentMap&lt;String, Double&gt; collect29 = userList.stream().collect(Collectors.&lt;User, String, Double&gt;toConcurrentMap(User::getUsername, User::getHeight, <span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;Double&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Double <span class="title function_">apply</span><span class="params">(Double s, Double s2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> s + s2;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为并发集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect29);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toConcurrentMap()方法</span></span><br><span class="line">    ConcurrentMap&lt;String, Double&gt; collect30 = userList.stream().collect(Collectors.&lt;User, String, Double, ConcurrentMap&lt;String, Double&gt;&gt;toConcurrentMap(User::getUsername, User::getHeight, <span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;Double&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Double <span class="title function_">apply</span><span class="params">(Double s, Double s2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> s + s2;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;, <span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;ConcurrentMap&lt;String, Double&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> ConcurrentMap&lt;String, Double&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ConcurrentHashMap</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为并发集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect30);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toList()方法</span></span><br><span class="line">    List&lt;User&gt; collect31 = userList.stream().collect(Collectors.toList());</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为列表：&quot;</span>);</span><br><span class="line">    System.out.println(collect31);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toMap()方法</span></span><br><span class="line">    Map&lt;Double, String&gt; collect32 = userList.stream().collect(Collectors.toMap(User::getHeight, User::getUsername));</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect32);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toMap()方法</span></span><br><span class="line">    Map&lt;String, Double&gt; collect33 = userList.stream().collect(Collectors.toMap(User::getUsername, User::getHeight, <span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;Double&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Double <span class="title function_">apply</span><span class="params">(Double aDouble, Double aDouble2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> aDouble + aDouble2;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect33);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toMap()方法</span></span><br><span class="line">    Map&lt;String, Double&gt; collect34 = userList.stream().collect(Collectors.toMap(User::getUsername, User::getHeight, <span class="keyword">new</span> <span class="title class_">BinaryOperator</span>&lt;Double&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Double <span class="title function_">apply</span><span class="params">(Double aDouble, Double aDouble2)</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> aDouble + aDouble2;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;, <span class="keyword">new</span> <span class="title class_">Supplier</span>&lt;Map&lt;String, Double&gt;&gt;() &#123;</span><br><span class="line">        <span class="meta">@Override</span></span><br><span class="line">        <span class="keyword">public</span> Map&lt;String, Double&gt; <span class="title function_">get</span><span class="params">()</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">HashMap</span>&lt;&gt;();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;));</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect34);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 测试toMap()方法</span></span><br><span class="line">    Set&lt;User&gt; collect35 = userList.stream().collect(Collectors.toSet());</span><br><span class="line">    System.out.println(<span class="string">&quot;转换为set集合：&quot;</span>);</span><br><span class="line">    System.out.println(collect35);</span><br><span class="line">    System.out.println(<span class="string">&quot;-----------------------&quot;</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>控制台输出：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br></pre></td><td class="code"><pre><span class="line">求用户平均身高：</span><br><span class="line">168.83333333333334</span><br><span class="line">-----------------------</span><br><span class="line">求用户平均年龄：</span><br><span class="line">23.5</span><br><span class="line">-----------------------</span><br><span class="line">求用户平均年龄：</span><br><span class="line">23.5</span><br><span class="line">-----------------------</span><br><span class="line">先根据年龄分组，在统计分组数量：</span><br><span class="line">4</span><br><span class="line">-----------------------</span><br><span class="line">统计用户数量：</span><br><span class="line">6</span><br><span class="line">-----------------------</span><br><span class="line">根据用户年龄分组：</span><br><span class="line">&#123;32=[User(age=32, height=180.0, weight=79.0, username=wangwu)], 18=[User(age=18, height=160.0, weight=50.0, username=zhangsan)], 21=[User(age=21, height=162.0, weight=70.0, username=zhangsan), User(age=21, height=169.0, weight=72.0, username=zhaoliu), User(age=21, height=170.0, weight=72.0, username=zhaoliu)], 28=[User(age=28, height=172.0, weight=56.0, username=lisi)]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">根据用户年龄分组，再获取姓名列表：</span><br><span class="line">&#123;32=[wangwu], 18=[zhangsan], 21=[zhangsan, zhaoliu, zhaoliu], 28=[lisi]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">根据用户年龄分组，再获取姓名列表：</span><br><span class="line">&#123;32=[wangwu], 18=[zhangsan], 21=[zhangsan, zhaoliu, zhaoliu], 28=[lisi]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">根据用户年龄分组：</span><br><span class="line">&#123;32=[User(age=32, height=180.0, weight=79.0, username=wangwu)], 18=[User(age=18, height=160.0, weight=50.0, username=zhangsan)], 21=[User(age=21, height=162.0, weight=70.0, username=zhangsan), User(age=21, height=169.0, weight=72.0, username=zhaoliu), User(age=21, height=170.0, weight=72.0, username=zhaoliu)], 28=[User(age=28, height=172.0, weight=56.0, username=lisi)]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">根据用户年龄分组，再获取姓名列表：</span><br><span class="line">&#123;32=[wangwu], 18=[zhangsan], 21=[zhangsan, zhaoliu, zhaoliu], 28=[lisi]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">根据用户年龄分组，再获取姓名列表：</span><br><span class="line">&#123;32=[wangwu], 18=[zhangsan], 21=[zhangsan, zhaoliu, zhaoliu], 28=[lisi]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">输出年龄拼接：</span><br><span class="line">zhangsanlisiwangwuzhangsanzhaoliuzhaoliu</span><br><span class="line">-----------------------</span><br><span class="line">输出年龄拼接，以逗号分割：</span><br><span class="line">zhangsan,lisi,wangwu,zhangsan,zhaoliu,zhaoliu</span><br><span class="line">-----------------------</span><br><span class="line">输出年龄拼接，以逗号分割：</span><br><span class="line">zhangsan,lisi,wangwu,zhangsan,zhaoliu,zhaoliu</span><br><span class="line">-----------------------</span><br><span class="line">求年龄最大的用户：</span><br><span class="line">User(age=32, height=180.0, weight=79.0, username=wangwu)</span><br><span class="line">-----------------------</span><br><span class="line">求年龄最小的用户：</span><br><span class="line">User(age=18, height=160.0, weight=50.0, username=zhangsan)</span><br><span class="line">-----------------------</span><br><span class="line">以年龄30岁为分界线：</span><br><span class="line">&#123;false=[User(age=18, height=160.0, weight=50.0, username=zhangsan), User(age=28, height=172.0, weight=56.0, username=lisi), User(age=21, height=162.0, weight=70.0, username=zhangsan), User(age=21, height=169.0, weight=72.0, username=zhaoliu), User(age=21, height=170.0, weight=72.0, username=zhaoliu)], true=[User(age=32, height=180.0, weight=79.0, username=wangwu)]&#125;</span><br><span class="line">-----------------------</span><br><span class="line">以年龄30岁为分界线：</span><br><span class="line">&#123;false=5, true=1&#125;</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">User(age=141, height=null, weight=null, username=null)</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">User(age=141, height=null, weight=null, username=null)</span><br><span class="line">-----------------------</span><br><span class="line">求年龄和：</span><br><span class="line">141</span><br><span class="line">-----------------------</span><br><span class="line">获取身高统计信息：</span><br><span class="line">最高身高：180.0</span><br><span class="line">身高数量：6</span><br><span class="line">平均身高：168.83333333333334</span><br><span class="line">最矮身高：160.0</span><br><span class="line">身高总和：1013.0</span><br><span class="line">-----------------------</span><br><span class="line">获取年龄统计信息：</span><br><span class="line">最大年龄：32</span><br><span class="line">年龄数量：6</span><br><span class="line">平均年龄：23.5</span><br><span class="line">最低年龄：18</span><br><span class="line">年龄总和：141</span><br><span class="line">-----------------------</span><br><span class="line">获取年龄统计信息：</span><br><span class="line">最大年龄：32</span><br><span class="line">年龄数量：6</span><br><span class="line">平均年龄：23.5</span><br><span class="line">最低年龄：18</span><br><span class="line">年龄总和：141</span><br><span class="line">-----------------------</span><br><span class="line">身高总和：</span><br><span class="line">1013.0</span><br><span class="line">-----------------------</span><br><span class="line">年龄总和：</span><br><span class="line">141</span><br><span class="line">-----------------------</span><br><span class="line">年龄总和：</span><br><span class="line">141</span><br><span class="line">-----------------------</span><br><span class="line">转换为集合：</span><br><span class="line">[User(age=18, height=160.0, weight=50.0, username=zhangsan), User(age=28, height=172.0, weight=56.0, username=lisi), User(age=32, height=180.0, weight=79.0, username=wangwu), User(age=21, height=162.0, weight=70.0, username=zhangsan), User(age=21, height=169.0, weight=72.0, username=zhaoliu), User(age=21, height=170.0, weight=72.0, username=zhaoliu)]</span><br><span class="line">-----------------------</span><br><span class="line">转换为并发集合：</span><br><span class="line">&#123;160.0=zhangsan, 162.0=zhangsan, 172.0=lisi, 169.0=zhaoliu, 170.0=zhaoliu, 180.0=wangwu&#125;</span><br><span class="line">-----------------------</span><br><span class="line">转换为并发集合：</span><br><span class="line">&#123;lisi=172.0, zhaoliu=339.0, zhangsan=322.0, wangwu=180.0&#125;</span><br><span class="line">-----------------------</span><br><span class="line">转换为并发集合：</span><br><span class="line">&#123;lisi=172.0, zhaoliu=339.0, zhangsan=322.0, wangwu=180.0&#125;</span><br><span class="line">-----------------------</span><br><span class="line">转换为列表：</span><br><span class="line">[User(age=18, height=160.0, weight=50.0, username=zhangsan), User(age=28, height=172.0, weight=56.0, username=lisi), User(age=32, height=180.0, weight=79.0, username=wangwu), User(age=21, height=162.0, weight=70.0, username=zhangsan), User(age=21, height=169.0, weight=72.0, username=zhaoliu), User(age=21, height=170.0, weight=72.0, username=zhaoliu)]</span><br><span class="line">-----------------------</span><br><span class="line">转换为集合：</span><br><span class="line">&#123;162.0=zhangsan, 160.0=zhangsan, 170.0=zhaoliu, 169.0=zhaoliu, 172.0=lisi, 180.0=wangwu&#125;</span><br><span class="line">-----------------------</span><br><span class="line">转换为集合：</span><br><span class="line">&#123;lisi=172.0, zhaoliu=339.0, zhangsan=322.0, wangwu=180.0&#125;</span><br><span class="line">-----------------------</span><br><span class="line">转换为集合：</span><br><span class="line">&#123;lisi=172.0, zhaoliu=339.0, zhangsan=322.0, wangwu=180.0&#125;</span><br><span class="line">-----------------------</span><br><span class="line">转换为set集合：</span><br><span class="line">[User(age=32, height=180.0, weight=79.0, username=wangwu), User(age=21, height=162.0, weight=70.0, username=zhangsan), User(age=21, height=169.0, weight=72.0, username=zhaoliu), User(age=18, height=160.0, weight=50.0, username=zhangsan), User(age=21, height=170.0, weight=72.0, username=zhaoliu), User(age=28, height=172.0, weight=56.0, username=lisi)]</span><br><span class="line">-----------------------</span><br></pre></td></tr></table></figure>

<h3 id="StreamSupport"><a href="#StreamSupport" class="headerlink" title="StreamSupport"></a>StreamSupport</h3><p>StreamSupport用于创建和操作流的低级实用程序方法。</p>
<p>这个类主要是为库编写人员提供数据结构的流视图，大多数面向最终用户的静态流方法都在各种stream类中。</p>
<p>StreamSupport提供以下方法：</p>
<table>
<thead>
<tr>
<th><strong>方法类型及返回值</strong></th>
<th><strong>方法名称</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>static DoubleStream</td>
<td>doubleStream(Spliterator.OfDouble spliterator, boolean parallel)</td>
<td>创建一个新的串行或并行 DoubleStream从 Spliterator.OfDouble。</td>
</tr>
<tr>
<td>static DoubleStream</td>
<td>doubleStream(Supplier&lt;? extends Spliterator.OfDouble&gt; supplier, int characteristics, boolean parallel)</td>
<td>创建一个新的顺序或并行 DoubleStream从 Supplier的 Spliterator.OfDouble。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>intStream(Spliterator.OfInt spliterator, boolean parallel)</td>
<td>创建一个新的串行或并行 IntStream从 Spliterator.OfInt。</td>
</tr>
<tr>
<td>static IntStream</td>
<td>intStream(Supplier&lt;? extends Spliterator.OfInt&gt; supplier, int characteristics, boolean parallel)</td>
<td>创建一个新的顺序或并行 IntStream从 Supplier的 Spliterator.OfInt。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>longStream(Spliterator.OfLong spliterator, boolean parallel)</td>
<td>创建一个新的串行或并行 LongStream从 Spliterator.OfLong。</td>
</tr>
<tr>
<td>static LongStream</td>
<td>longStream(Supplier&lt;? extends Spliterator.OfLong&gt; supplier, int characteristics, boolean parallel)</td>
<td>创建一个新的顺序或并行 LongStream从 Supplier的 Spliterator.OfLong。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>stream(Spliterator<T> spliterator, boolean parallel)</td>
<td>创建一个新的串行或并行 Stream从 Spliterator。</td>
</tr>
<tr>
<td>static <T> Stream<T></td>
<td>stream(Supplier&lt;? extends Spliterator<T>&gt; supplier, int characteristics, boolean parallel)</td>
<td>创建一个新的顺序或并行 Stream从 Supplier的 Spliterator。</td>
</tr>
</tbody></table>
<p>以构建Steam为例，打开Stream.of()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span>&lt;T&gt; Stream&lt;T&gt; <span class="title function_">of</span><span class="params">(T t)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> StreamSupport.stream(<span class="keyword">new</span> <span class="title class_">Streams</span>.StreamBuilderImpl&lt;&gt;(t), <span class="literal">false</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>调用的是StreamSupport的stream()方法构造Stream实现。</p>
<p>进入StreamSupport的stream()方法：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> &lt;T&gt; Stream&lt;T&gt; <span class="title function_">stream</span><span class="params">(Spliterator&lt;T&gt; spliterator, <span class="type">boolean</span> parallel)</span> &#123;</span><br><span class="line">    Objects.requireNonNull(spliterator);</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="title class_">ReferencePipeline</span>.Head&lt;&gt;(spliterator,</span><br><span class="line">                                        StreamOpFlag.fromCharacteristics(spliterator),</span><br><span class="line">                                        parallel);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>发现最终返回的是一个ReferencePipeline的静态内部类Head。</p>
</article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href>狼族少年、血狼</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://geekwolfman.github.io/2023/05/02/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Stream%E6%B5%81.html">https://geekwolfman.github.io/2023/05/02/一文详解Stream流.html</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://geekwolfman.github.io" target="_blank">狼族少年、血狼</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/java%E5%9F%BA%E7%A1%80/">java基础</a></div><div class="post_share"><div class="social-share" data-image="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Stream%E6%B5%81/00cover.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/2023/05/06/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Optional.html" title="一文详解Optional"><img class="cover" src="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Optional/00cover.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">一文详解Optional</div></div></a></div><div class="next-post pull-right"><a href="/2023/04/22/%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E8%AE%A1%E7%AE%97%E5%99%A8.html" title="实现一个计算器"><img class="cover" src="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA%E8%AE%A1%E7%AE%97%E5%99%A8/00cover.jpg" onerror="onerror=null;src='/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">实现一个计算器</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/2023/05/06/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Optional.html" title="一文详解Optional"><img class="cover" src="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/%E4%B8%80%E6%96%87%E8%AF%A6%E8%A7%A3Optional/00cover.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-05-06</div><div class="title">一文详解Optional</div></div></a></div><div><a href="/2023/04/04/Java%E4%B8%ADi=i-%E9%97%AE%E9%A2%98.html" title="Java中i&#x3D;i++问题"><img class="cover" src="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/articles/Java%E4%B8%ADi%3Di%2B%2B%E9%97%AE%E9%A2%98/01cover.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2023-04-04</div><div class="title">Java中i&#x3D;i++问题</div></div></a></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="https://geekwolfman-blog.oss-cn-chengdu.aliyuncs.com/config/avatar/avatar.png" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">狼族少年、血狼</div><div class="author-info__description"></div></div><div class="card-info-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">57</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">14</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">9</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://wpa.qq.com/msgrd?v=3&amp;uin=2370032534&amp;site=qq&amp;menu=yes&amp;jumpflag=1"><i class="fa-brands fa-qq"></i><span>添加博主QQ</span></a></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">本站所有博文均是博主的学习笔记与个人理解，来源于网络，如有<span style="color:red;font-weight:bold;">侵权</span>请<a target="_blank" rel="noopener" href="https://wpa.qq.com/msgrd?v=3&uin=2370032534&site=qq&menu=yes&jumpflag=1" style="color:#49B1F5;font-weight:bold">联系我</a>进行删除🥰。</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%AE%80%E4%BB%8B"><span class="toc-number">1.</span> <span class="toc-text">简介</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%89%B9%E6%80%A7"><span class="toc-number">2.</span> <span class="toc-text">特性</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B9%B6%E8%A1%8C%E6%80%A7"><span class="toc-number">2.1.</span> <span class="toc-text">并行性</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9D%9E%E5%B9%B2%E6%89%B0"><span class="toc-number">2.2.</span> <span class="toc-text">非干扰</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9C%89%E7%8A%B6%E6%80%81"><span class="toc-number">2.3.</span> <span class="toc-text">有状态</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%89%AF%E4%BD%9C%E7%94%A8"><span class="toc-number">2.4.</span> <span class="toc-text">副作用</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9C%89%E5%BA%8F%E6%80%A7"><span class="toc-number">2.5.</span> <span class="toc-text">有序性</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BD%92%E7%BA%A6%E6%93%8D%E4%BD%9C"><span class="toc-number">2.6.</span> <span class="toc-text">归约操作</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8F%AF%E5%8F%98%E5%BD%92%E7%BA%A6"><span class="toc-number">2.7.</span> <span class="toc-text">可变归约</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BD%8E%E7%BA%A7%E6%B5%81%E6%9E%84%E9%80%A0%E5%99%A8"><span class="toc-number">2.8.</span> <span class="toc-text">低级流构造器</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0"><span class="toc-number">3.</span> <span class="toc-text">实现</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9E%9A%E4%B8%BE"><span class="toc-number">3.1.</span> <span class="toc-text">枚举</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9E%9A%E4%B8%BE%E5%B8%B8%E9%87%8F"><span class="toc-number">3.1.1.</span> <span class="toc-text">枚举常量</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%89%80%E6%9C%89%E6%96%B9%E6%B3%95"><span class="toc-number">3.1.2.</span> <span class="toc-text">所有方法</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%8E%A5%E5%8F%A3"><span class="toc-number">3.2.</span> <span class="toc-text">接口</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0%E7%B1%BB"><span class="toc-number">3.3.</span> <span class="toc-text">实现类</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%A4%BA%E4%BE%8B"><span class="toc-number">4.</span> <span class="toc-text">示例</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%8E%A5%E5%8F%A3-1"><span class="toc-number">4.1.</span> <span class="toc-text">接口</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#BaseStream"><span class="toc-number">4.1.1.</span> <span class="toc-text">BaseStream</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Collector"><span class="toc-number">4.1.2.</span> <span class="toc-text">Collector</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DoubleStream"><span class="toc-number">4.1.3.</span> <span class="toc-text">DoubleStream</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DoubleStream-Builder"><span class="toc-number">4.1.4.</span> <span class="toc-text">DoubleStream.Builder</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#IntStream"><span class="toc-number">4.1.5.</span> <span class="toc-text">IntStream</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#IntStream-Builder"><span class="toc-number">4.1.6.</span> <span class="toc-text">IntStream.Builder</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#LongStream"><span class="toc-number">4.1.7.</span> <span class="toc-text">LongStream</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#LongStream-Builder"><span class="toc-number">4.1.8.</span> <span class="toc-text">LongStream.Builder</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Stream"><span class="toc-number">4.1.9.</span> <span class="toc-text">Stream</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Stream-Builder"><span class="toc-number">4.1.10.</span> <span class="toc-text">Stream.Builder</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%B1%BB"><span class="toc-number">4.2.</span> <span class="toc-text">类</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Collectors"><span class="toc-number">4.2.1.</span> <span class="toc-text">Collectors</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#StreamSupport"><span class="toc-number">4.2.2.</span> <span class="toc-text">StreamSupport</span></a></li></ol></li></ol></li></ol></div></div></div></div></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;2020 - 2023 By 狼族少年、血狼</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><div class="js-pjax"></div><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="false" data-click="false"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div><script src="/js/search/local-search.js"></script></div></body></html>